VBA web scraper to access search results from JavaScript form - javascript

I am working on a web scraper in VBA.
I have a website with a JavaScript form and I don't know how to access a table from the search results of that JavaScript form.
I know how to navigate and pull out the required info from a normal HTML site. I already put in my searching keywords and click the "search" button all through VBA.
After my search (e.g. "SN857X00PE") the search results are displayed in a table:
SN857X00PE/01 StudioLine 9702 - 9709
SN857X00PE/38 StudioLine 9711 - 9801
SN857X00PE/42 StudioLine 9802 - 9804
SN857X00PE/46 StudioLine 9805 - 9806
I'm looking to access all the left serial numbers (e.g. SN857X00PE/01, SN857X00PE/38 etc.).
When I go into the Firefox debugger I see many .js files and an index.xhtml.
I can find everything I need in the index.xhtml file (code included below with example search SN857X00PE) but when I access the HTML through IE.Document.getElementById("body").InnerHtml it doesn't show me the content of the index.xhtml file but instead the content of the TP4.js file (code below).
As you can see below, the TP4.js file doesn't include any useful info about the search results or any way to access them.
Is there a way to access the search result table of the JavaScript form? If I am able to put keywords in it and make the search result inside VBA it should be possible the access the results too. I'd like IE.Documents to point to the content of the index.xhtml file instead of the default TP4.js file if that's possible.
When I go to the Firefox inspector to see the HTML the javascript website is producing in the end it looks so easy to access my information. Is there a way to get direct access to the nice and clean "endresult-html" after the browser finishes compiling all the JavaScript?
The website is tradeplace(DOT)com but the Javascript form is hidden behind a login.
Here an overview on how the site looks like when it displays the search results. On the right I am showing the table with the search results inside the index.xhtml that I am trying to access but I don't know how to reach it, since I only have access to the contents of the tp4.js file.
Due to max character limit, I couldn't include the whole HTML code, here are some parts I think could be important/relevant, so you can get a general idea how the site looks:
index.xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="head">
<title>Tradeplace Marketplace</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="/tp4-web/css/jquery.theme.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/tp4-web/javax.faces.resource/jquery/jquery.js.xhtml?ln=primefaces&v=6.0"></script>
<script type="text/javascript" src="/tp4-web/javax.faces.resource/core.js.xhtml?ln=primefaces&v=6.0"></script>
<script type="text/javascript" src="/tp4-web/javax.faces.resource/jsf.js.xhtml?ln=javax.faces"></script>
<link rel="stylesheet" type="text/css" href="/tp4-web/javax.faces.resource/components.css.xhtml?ln=primefaces&v=6.0" />
<script type="text/javascript" src="/tp4-web/javax.faces.resource/components.js.xhtml?ln=primefaces&v=6.0"></script>
<script type="text/javascript" src="/tp4-web/javax.faces.resource/jquery/jquery-plugins.js.xhtml?ln=primefaces&v=6.0"></script>
<script type="text/javascript" src="/tp4-web/javax.faces.resource/primefaces-extensions.js.xhtml?ln=primefaces-extensions&v=6.0.0"></script>
<script type="text/javascript">
if (window.PrimeFaces) {
PrimeFaces.settings.locale = 'en_US';
}
</script>
<link href="/tp4-web/css/tp4.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/tp4-web/js/tp4.js"></script>
</head>
<body id="body">
<script type="text/javascript">
$(document).ready(function() {
TP4.initPageLayout();
TP4.enableSubmenus();
});
$(window).unload(function() {
TP4.hideLoadingScreen();
});
</script>
<div id="page">
<div id="header">
<div id="logoline" class="clearfix">
<img id="mainLogo" src="/tp4-web/images/sparetable/logo-tradeplace.png" alt="tradeplace" />
<img id="sparesLogo" src="/tp4-web/images/sparetable/spares.png" alt="spares" />
<table id="oemLogo">
<tr>
<td valign="middle"><img id="logoLine:brandImage" src="/tp4-web/pages/streamImage.xhtml?type=1&identifier=100001&pfdrid_c=true" alt="" />
</td>
</tr>
</table>
</div>
------------------------------------------------------------------------- ... SKIPPING SOME CODE UP TO THE RELEVANT CODE PART -------------------------------------------------------------------------
<tr class="data alt">
<td>
<a href="/tp4-web/pages/secure/product/productSearchDetail.xhtml?productNumber=SN857X00PE%2F01&formattedProductNumber=SN857X00PE%2F01&windowId=909" onclick="TP4.showLoadingScreen(this)">
SN857X00PE/01
</a>
</td>
<td>
StudioLine
</td>
<td>9702 - 9709
</td>
<td valign="middle" class="nowrap">
<span>
<a href="/tp4-web/pages/secure/product/productSearchDetail.xhtml?productNumber=SN857X00PE%2F01&formattedProductNumber=SN857X00PE%2F01&windowId=909" onclick="TP4.showLoadingScreen(this)">
<img alt="Dokumente" title="Dokumente" src="/tp4-web/images/icons/docs.gif" /></a>
</span>
<span>
<a href="/tp4-web/pages/secure/product/part/productPartList.xhtml?productNumber=SN857X00PE%2F01&formattedProductNumber=SN857X00PE%2F01&windowId=909" onclick="TP4.showLoadingScreen(this)">
<img alt="Ersatzteilliste" title="Ersatzteilliste" src="/tp4-web/images/icons/spare.gif" /></a>
</span>
<span>
<a href="/tp4-web/pages/secure/product/explodedView.xhtml?productNumber=SN857X00PE%2F01&formattedProductNumber=SN857X00PE%2F01&typeId1=A02&typeId2=A02E32&typeId3=A02E32V&windowId=909" onclick="TP4.showLoadingScreen(this)">
<img alt="Explosionszeichnung" title="Explosionszeichnung" src="/tp4-web/images/icons/explos.gif" /></a>
</span>
<span>
<a href="/tp4-web/pages/secure/accessory/accessoryForProduct.xhtml?commercialItemNumber=SN857X00PE%2F01&commercialItemNumberFormatted=SN857X00PE%2F01&windowId=909" onclick="TP4.showLoadingScreen(this)">
<img alt="Zubehör" title="Zubehör" src="/tp4-web/images/icons/commercial.gif" /></a>
</span>
</td>
</tr>
-------------------------------------------------------------- SKIPPING CODE AGAIN TO THE END -------------------------------------------------------------
</div>
<div id="ajaxStatus"></div>
<script id="ajaxStatus_s" type="text/javascript">
$(function() {
PrimeFaces.cw("AjaxStatus", "ajaxStatusWidget", {
id: "ajaxStatus",
start: function() {
TP4.showLoadingScreen();
},
success: function() {
TP4.hideLoadingScreen();
}
});
});
</script>
<div id="loadingDialog" class="ui-dialog ui-widget ui-widget-content ui-corner-all ui-shadow ui-hidden-container">
<div class="ui-dialog-content ui-widget-content">
<table id="loadingScreen">
<tr>
<td>
<p><b>Bitte warten - Datenbeschaffung...</b></p>
</td>
<td><img src="/tp4-web/images/ajax-loading.gif" /></td>
</tr>
</table>
</div>
</div>
<script id="loadingDialog_s" type="text/javascript">
$(function() {
PrimeFaces.cw("Dialog", "loadingDialogWidget", {
id: "loadingDialog",
resizable: false,
modal: true
});
});
</script>
</body>
<script type="text/javascript">
(function(i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function() {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-55961901-1', 'auto');
ga('set', '&uid', '27d62c9d4ec32f32a829bed7142036c05d9516ac93c8935d18acf1fdc3d59145');
ga('send', 'pageview', {
'title': 'ProductSearchResult'
});
</script>
</html>
TP4.js
PrimeFaces.widget.ExtImageAreaSelect && (PrimeFaces.widget.ExtImageAreaSelect.prototype.cancelSelection = function () {
this.instance && this.instance.cancelSelection()
});
TP4 = {
Constants: {
PAGE_ELEMENT_SELECTOR: '#page',
HEADER_ELEMENT_SELECTOR: '#header',
FOOTER_ELEMENT_SELECTOR: '#footer',
BASKET_RELOAD_LINK_ID: '#reloadBasketLink',
BASKET_POPUP_WIDTH: '460',
BASKET_POPUP_HEIGHT: '400',
SPECIAL_NOTICE_PART_POPUP_WIDTH: '380',
SPECIAL_NOTICE_PART_POPUP_HEIGHT: '365',
SPECIAL_NOTICE_DOCUMENT_LIST_POPUP_WIDTH: '600',
SPECIAL_NOTICE_DOCUMENT_LIST_POPUP_HEIGHT: '400',
SPECIAL_NOTICE_DOCUMENT_POPUP_WIDTH: '500',
SPECIAL_NOTICE_DOCUMENT_POPUP_HEIGHT: '200',
CUSTOMER_INFO_POPUP_WIDTH: '480',
CUSTOMER_INFO_POPUP_HEIGHT: '405',
SMALL_POPUP_WIDTH: '360',
SMALL_POPUP_HEIGHT: '330',
MEDIUM_POPUP_WIDTH: '800',
MEDIUM_POPUP_HEIGHT: '600',
NON_MODAL_DIALOG_Z_INDEX: 500
},
Context: {
currentDialogZIndex: 0
},
showLoadingScreen: function (a) {
a ? !a.href || a.href && '#' == a.href ? TP4.showLoadingScreenAfterTimeout() : a.href && PF('loadingDialogWidget').show() : PF('loadingDialogWidget').show()
},
showLoadingScreenAfterTimeout: function () {
setTimeout(function () {
PF('loadingDialogWidget').show()
}, 100)
},
hideLoadingScreen: function () {
PF('loadingDialogWidget').hide()
},
initPageLayout: function () {
$(TP4.Constants.PAGE_ELEMENT_SELECTOR).css({
'padding-top': $(TP4.Constants.HEADER_ELEMENT_SELECTOR).height(),
'padding-bottom': $(TP4.Constants.FOOTER_ELEMENT_SELECTOR).height()
})
},
adjustElementHeightToAvailableHeight: function (a, b) {
var c = $(a),
d = $(TP4.Constants.HEADER_ELEMENT_SELECTOR),
g = $(TP4.Constants.FOOTER_ELEMENT_SELECTOR),
e = $(window).height();
0 < d.length && (e -= d.height());
0 < g.length && (e -= g.height());
null != b && (e -= b);
c.height(e)
},
setElementCssHeightToContentHeight: function (a) {
a = $(a);
var b = a.height();
a.css('height', b + 'px')
},
setDefaultCommand: function (a, b) {
a.keydown(function (a) {
var d = $.ui.keyCode;
if (a.which ==
d.ENTER || a.which == d.NUMPAD_ENTER) b.click(),
a.preventDefault()
})
},
scrollTo: function (a) {
window.location.hash = '#' + a
},
scrollToTop: function () {
$('html, body').animate({
scrollTop: 0
}, 0)
},
scrollToBottom: function (a) {
$('html, body').animate({
scrollTop: $(document).height()
}, a)
},
adjustMarginForTwoColumnLayout: function (a, b) {
$(b).css({
'margin-left': $(a).width()
})
},
restoreInputFieldValueFromHtml: function (a) {
a.each(function (b) {
$(this).val(a[b].defaultValue)
})
},
disableLoadingScreenModality: function () {
PF('loadingDialogWidget').cfg.modal = !1
},
enableLoadingScreenModality: function () {
PF('loadingDialogWidget').cfg.modal = !0
},
moveDialogBehindModalContainer: function (a) {
TP4.Context.currentDialogZIndex = a.jq.css('z-index');
a.jq.css('z-index', TP4.Constants.NON_MODAL_DIALOG_Z_INDEX)
},
moveDialogBeforeModalContainer: function (a) {
a.jq.css('z-index', TP4.Context.currentDialogZIndex)
},
synchronizeDialogModality: function (a) {
TP4.disableLoadingScreenModality();
TP4.moveDialogBehindModalContainer(a)
},
resetDialogModalityToDefault: function (a) {
TP4.enableLoadingScreenModality();
TP4.moveDialogBeforeModalContainer(a)
},
activateMaxLengthHandlingOnTextareas: function () {
$('textarea[maxlength]').keyup(function () {
var a = parseInt($(this).attr('maxlength'));
$(this).val().length > a && $(this).val($(this).val().substr(0, $(this).attr('maxlength')))
})
},
resizeTo: function (a, b, c) {
var d = - 1 < navigator.userAgent.toLowerCase().indexOf('chrome');
null != a && (d ? setTimeout(function () {
a.resizeTo(b, c)
}, 4) : a.resizeTo(b, c))
},
enableSubmenus: function () {
$('li').hover(function () {
var a = $(this);
a.closest('ul').children('li.hover').removeClass('hover');
a.addClass('hover');
a.attr('isHovered', !0)
}, function () {
var a = $(this);
a.removeAttr('isHovered');
setTimeout(function () {
a.attr('isHovered') || a.removeClass('hover')
}, 350)
})
},
redirect: function (a) {
window.location.href = a
},
overwriteIfZero: function (a) {
0 < a.value.length && '0' == a.value.substring(0, 1) && (a.value = a.value.substring(1), TP4.overwriteIfZero(a))
},
Part: {
showChildList: function (a) {
$('#childList' + a).show();
$('#showChildList' + a).hide();
$('#hideChildList' + a).show()
},
hideChildList: function (a) {
$('#childList' +
a).hide();
$('#showChildList' + a).show();
$('#hideChildList' + a).hide()
},
setAllDefaultCommands: function () {
TP4.setDefaultCommand($('#inputTextDescription'), $('#commandLinkDescription'));
TP4.setDefaultCommand($('#inputTextPartNumber'), $('#commandLinkPartNumber'));
TP4.setDefaultCommand($('#inputTextPicPos'), $('#commandLinkPicPos'))
}
},
Basket: {
openAddToBasketPopUp: function (a) {
TP4.PopUp.openPopUpWithSize(a.href, a.target, TP4.Constants.BASKET_POPUP_WIDTH, TP4.Constants.BASKET_POPUP_HEIGHT, 0, 0);
return !1
},
initializeDatePicker: function (a) {
a = $('#requestDeliveryDate').datepicker({
dateFormat: 'yy-mm-dd',
changeMonth: !0,
changeYear: !0,
yearRange: '-90:+0',
showOn: 'button',
buttonImageOnly: !0,
buttonImage: a + '/images/calendar.gif',
minDate: 0
});
a.attr('readonly', !0);
a.datepicker('option', 'showAnim', 'show')
},
setAllDefaultCommands: function () {
TP4.setDefaultCommand($('#basketOverviewItemListWrapper input'), $('#updateBasket'))
}
},
SpecialNotices: {
openSpecialNoticePartPopUp: function (a) {
TP4.PopUp.openPopUpWithSize(a.href, a.target, TP4.Constants.SPECIAL_NOTICE_PART_POPUP_WIDTH, TP4.Constants.SPECIAL_NOTICE_PART_POPUP_HEIGHT, 0, 0);
return !1
},
openSpecialNoticeDocumentListPopUp: function (a) {
TP4.PopUp.openPopUpWithSize(a.href, a.target, TP4.Constants.SPECIAL_NOTICE_DOCUMENT_LIST_POPUP_WIDTH, TP4.Constants.SPECIAL_NOTICE_DOCUMENT_LIST_POPUP_HEIGHT, 0, 0);
return !1
},
openSpecialNoticeDocumentPopUp: function (a) {
TP4.PopUp.openPopUpWithSize(a.href, a.target, TP4.Constants.SPECIAL_NOTICE_DOCUMENT_POPUP_WIDTH, TP4.Constants.SPECIAL_NOTICE_DOCUMENT_POPUP_HEIGHT, 0, 0);
return !1
},
initializeDocumentView: function (a) {
if (a) {
a = $('#specialNoticeHeader');
var b = 0;
0 < a.length && (b = a.height());
$('#specialNoticesPdf').css('visibility', 'visible');
$.browser.webkit ? setTimeout(function () {
TP4.adjustElementHeightToAvailableHeight('#specialNoticesDocumentContainer', b)
}, 100) : TP4.adjustElementHeightToAvailableHeight('#specialNoticesDocumentContainer', b)
}
},
afterAddToBasket: function (a, b) {
b && TP4.SpecialNotices.initializeDocumentView(a);
TP4.SpecialNotices.triggerBasketRefreshInMainWindow();
scroll(0, 0)
},
triggerBasketRefreshInMainWindow: function () {
TP4.SpecialNotices.triggerBasketRefresh(window.opener)
},
triggerBasketRefresh: function (a) {
var b = a.$(TP4.Constants.BASKET_RELOAD_LINK_ID);
0 < b.length ? (a.TP4.showLoadingScreen(), a.location.href = b.attr('href')) : a.opener && TP4.SpecialNotices.triggerBasketRefresh(a.opener)
}
},
PopUp: {
openSmallPopUpForLink: function (a) {
TP4.PopUp.openPopUpWithSize(a.href, a.target, TP4.Constants.SMALL_POPUP_WIDTH, TP4.Constants.SMALL_POPUP_HEIGHT, 0, 0);
return !1
},
-----------------------------------------------------------------
SKIPPING CODE TO THE END
-------------------------------------------------------------------
Infoline: {
openCustomerInfoPopUpForLink: function (a) {
TP4.PopUp.openPopUpWithSize(a.href, a.target, TP4.Constants.CUSTOMER_INFO_POPUP_WIDTH, TP4.Constants.CUSTOMER_INFO_POPUP_HEIGHT, 0, 0);
return !1
},
triggerInfolineRefreshInMainWindow: function () {
var a = window.opener.$(TP4.Constants.BASKET_RELOAD_LINK_ID);
0 < a.length ? (window.opener.location.href = a.attr('href'), window.opener.TP4.showLoadingScreen()) : (window.opener.TP4.showLoadingScreen(), window.opener.location.search = TP4.Infoline.getOpenerUrlWithEmptyWindowId())
},
getOpenerUrlWithEmptyWindowId: function () {
for (var a = {
}, b = window.opener.location.search.substring(1), c = /([^&=]+)=([^&]*)/g, d; d = c.exec(b); ) a[decodeURIComponent(d[1])] = decodeURIComponent(d[2]);
a.windowId = '';
return $.param(a)
}
},
History: {
initializeDatePicker: function (a) {
var b = $('#dateFrom, #dateTo').datepicker({
dateFormat: 'yy-mm-dd',
changeMonth: !0,
changeYear: !0,
yearRange: '-90:+0',
showOn: 'button',
buttonImageOnly: !0,
buttonImage: a + '/images/calendar.gif',
onSelect: function (a) {
var d = 'dateFrom' == this.id ? 'minDate' :
'maxDate',
g = $(this).data('datepicker');
a = $.datepicker.parseDate(g.settings.dateFormat || $.datepicker._defaults.dateFormat, a, g.settings);
b.not(this).datepicker('option', d, a)
}
});
b.attr('readonly', !0);
b.datepicker('option', 'showAnim', 'show')
}
},
FAQ: {
Context: {
selectedIssueId: - 1,
selectedQuestionsIssueId: - 1,
selectedQuestionAnchor: ''
},
setSelectedIssueId: function (a) {
TP4.FAQ.Context.selectedIssueId = a;
TP4.FAQ.Context.selectedQuestionsIssueId = a
},
setSelectedQuestionsIssueId: function (a) {
TP4.FAQ.Context.selectedQuestionsIssueId = a;
- 1 === TP4.FAQ.Context.selectedIssueId && (TP4.FAQ.Context.selectedIssueId = a)
},
setSelectionQuestionAnchor: function (a) {
TP4.FAQ.Context.selectedQuestionAnchor = 'question' + a
},
areQuestionsAlreadyLoaded: function () {
if (TP4.FAQ.Context.selectedIssueId === TP4.FAQ.Context.selectedQuestionsIssueId) return TP4.FAQ.scrollToAnchor(),
!1;
TP4.FAQ.Context.selectedIssueId = TP4.FAQ.Context.selectedQuestionsIssueId
},
scrollToAnchor: function () {
TP4.scrollTo(TP4.FAQ.Context.selectedQuestionAnchor)
},
moveOnClickFromInnerLinkToTreeNodeContainer: function (a, b) {
$(a).find('.ui-treenode-leaf').each(function () {
var a = $(this).find(b),
d = a.attr('onclick');
$(this).attr('onclick', d);
a.attr('onclick', null)
})
}
}
};
PrimeFaces.widget.Poll = PrimeFaces.widget.BaseWidget.extend({
init: function (a) {
this.cfg = a;
this.id = this.cfg.id;
this.active = !1;
this.cfg.autoStart && this.start()
},
refresh: function (a) {
this.isActive() && this.stop();
this.init(a)
},
start: function () {
this.timer = setInterval(this.cfg.fn, 1000 * this.cfg.frequency);
this.active = !0
},
stop: function () {
clearInterval(this.timer);
this.active = !1
},
handleComplete: function (a, b, c) {
c.stop && this.stop()
},
isActive: function () {
return this.active
}
});

CSS selector:
So using the HTML supplied I can use a CSS selector as follows:
#productList td > a
This selects elements based on their styling. "#" stands for class. The td > a means, select all a elements where the parent is a td element. So select those inside of an element with class productList.
I apply the selector using the querySelectorAll method of document which returns a nodeList of matching elements, the length of which I then traverse.
I am reading your HTML in from a file but you could use:
ie.document.querySelectorAll("#productList td > a")
CSS query:
Output to immediate window:
VBA:
Option Explicit
Public Sub HTMLQuery()
Dim oXHTTP As Object, HTML As New HTMLDocument, aNodeList As Object, i As Long
Set oXHTTP = CreateObject("MSXML2.XMLHTTP")
With oXHTTP
.Open "GET", "C:\Users\User\Desktop\index.html", False
.send
HTML.body.innerHTML = oXHTTP.responseText
Set aNodeList = HTML.querySelectorAll("#productList td > a")
For i = 0 To aNodeList.Length - 1
Debug.Print aNodeList.item(i).innerText
Next i
End With
End Sub
For your code:
Dim aNodeList As Object
Set aNodeList = IE.document.querySelectorAll("#productList td > a")
For i = 0 To aNodeList.Length - 1
Debug.Print aNodeList.item(i).innerText
Next i
Looping with a timer for page to load:
While IE.Busy Or IE.readyState < 4: DoEvents: Wend
Dim t As Date
t = Timer
Do
DoEvents
On Error Resume Next
Set aNodeList = IE.document.querySelectorAll("#productList td > a")
On Error GoTo 0
If Timer - t = 3 Then Exit Do '<==To avoid infinite loop. Adjust 3 seconds as required
Loop While aNodeList Is Nothing
If Not aNodeList Is Nothing Then
For i = 0 To aNodeList.Length - 1
Debug.Print aNodeList.item(i).innerText
Next i
End If
References:
You need to go VBE > Tools > References and add a reference to HTML Object Library if using an HTMLDocument variable as I have. You don't need this is accessing direct from IE.document.

Related

JavaScript in slider image

I have a slider on my e-commerce homepage but it is freeze .I need to change it after 3 second .... Thanks in advance.
function aweMainSlider() {
var e = $(".main-slider");
e.owlCarousel({
items: 1,
nav: !0,
dots: !0,
onInitialized: function() {
e.find(".owl-item").each(function() {
var e = $(this),
o = e.find(".main-slider-item"),
a = e.find(".main-slider-image > img");
o.length && a.length && (o.addClass("background"),
o.css("background-image", "url(" + a.attr("src") + ")"), a.css({
opacity: 0,
visibility: "hidden"
}))
})
}
})
}

Adding or Creating "forEach" to function in javascript / jquery

First and foremost I'd like to thank everyone who participates contributes and adds to the forums / community, you guys provide an extremely appreciated and valued resource to those that just need information and assistance when needed. Simple thing to do for some, but to many it means volumes. So thanks again.
I'm no coding or script expert but I definitely learn quick and know enough to get around and translate (especially if the language is explained) attempting to get a player on my site to populate and propagate a playlist based on an uploaded file string.
So far I have the player completely up and running, it properly parses the upload links to display the separate mp3 files to play as well as the separate description information per file.
The problem is when I click the play button all of the files mp3 play at once. I'm almost positive I need to add a forEach statement or something along those lines either here:
$(function(){
$('#player1').plp({
'volume': 80,
'playlist':[
{"title":"{$pic.video_descr }",
"author":"{.Me}",
"cover":"files/covers/fullfilename",
"mfile":"{.siteurl}{.fullfilename}",
"duration":"330"},
]
});
});
for each title, author, cover, duration and mfile,
or somewhere around here
function init_track(i){
cpl = i;
$this.find('.playlist span').removeClass('active');
$this.find('.playlist span:eq('+i+')').addClass('active');
$audio.src = options.playlist[i].mfile;
$this.find('.title').html(options.playlist[i].title);
$this.find('.author').html(options.playlist[i].author);
$this.find('.cover').attr('src', options.playlist[i].cover);
}
for(i=0; i < options.playlist.length; i++){
$this.find('.playlist').append('<span>'+options.playlist[i].author+' - '+options.playlist[i].title+'</span>');
}
init_track(cpl);
$this.find('.playlist span').click(function(){
init_track($(this).index());
});
here is the full .js
(function($) {
jQuery.fn.plp = function(options) {
var options = $.extend({
volume: 50,
playlist: [],
autostart: false
}, options);
var make = function() {
var $this = $(this);
var cpl = 0;
var $audio = new Audio();
var isrand = false;
$this.find('.volume').slider({
animate: true,
range: 'min',
value: options.volume,
min: 0,
max: 1,
step: 0.01,
slide: function(event, ui) {
$audio.volume = ui.value;
}
});
$this.find('.long').slider({
animate: true,
range: 'min',
value: 0,
min: 0,
max: 60,
step: 1,
slide: function(event, ui) {
$audio.currentTime = ui.value;
}
});
$audio.addEventListener('canplay', function(_event) {
if ($audio.duration) {
$this.find('.all').html(' / ' + toMinit($audio.duration));
$this.find('.long').slider({
'max': $audio.duration
});
} else {
this.find('.all').html(' / ' + toMinit(options.playlist[cpl].duration));
$this.find('.long').slider({
'max': options.playlist[cpl].duration
});
}
if (options.autostart) {
$audio.play();
$this.find('.tlb_stop').addClass('isplay');
} else {
options.autostart = true;
}
});
$audio.addEventListener('ended', function() {
if (isrand) {
var rand = cpl;
while (rand == cpl) {
rand = Math.floor(Math.random((options.playlist.length)));
}
init_track(rand);
} else {
if (cpl == options.playlist.length - 1) {
cpl = -1;
}
init_track(cpl + 1);
}
});
$audio.addEventListener('timeupdate', function() {
$this.find('.long').slider({
'value': $audio.currentTime
});
$this.find('.current').html(toMinit($audio.currentTime));
});
function toMinit(val) {
val = Number(val);
var ost = Math.floor(val % 60);
var tm = Math.floor(val / 60);
if (ost < 10) {
ost = '0' + ost;
}
if (tm < 10) {
tm = '0' + tm;
}
return tm + ':' + ost;
}
function init_track(i) {
cpl = i;
$this.find('.playlist span').removeClass('active');
$this.find('.playlist span:eq(' + i + ')').addClass('active');
$audio.src = options.playlist[i].mfile;
$this.find('.title').html(options.playlist[i].title);
$this.find('.author').html(options.playlist[i].author);
$this.find('.cover').attr('src', options.playlist[i].cover);
}
for (i = 0; i < options.playlist.length; i++) {
$this.find('.playlist').append('<span>' + options.playlist[i].author + ' - ' + options.playlist[i].title + ' < /span>');
}
init_track(cpl);
$this.find('.playlist span').click(function() {
init_track($(this).index());
});
$this.find('.tlb_prev').click(function() {
if (isrand) {
var rand = cpl;
while (rand == cpl) {
rand = Math.floor(Math.random() *
(options.playlist.length));
}
init_track(rand);
} else {
if (cpl === 0) {
cpl = options.playlist.length;
}
init_track(cpl - 1);
}
return false;
});
$this.find('.tlb_stop').click(function() {
if ($audio.paused) {
$audio.play();
$(this).addClass('isplay');
} else {
$audio.pause();
$(this).removeClass('isplay');
}
return false;
});
$this.find('.tlb_next').click(function() {
if (isrand) {
var rand = cpl;
while (rand == cpl) {
rand = Math.floor(Math.random() *
(options.playlist.length));
}
init_track(rand);
} else {
if (cpl == options.playlist.length - 1) {
cpl = -1;
}
init_track(cpl + 1);
}
return false;
});
$this.find('.vol_icon').click(function() {
$(this).toggleClass('active');
$this.find('.volume').fadeToggle(100);
return false;
});
$this.find('.pl_icon').click(function() {
$(this).toggleClass('active');
$this.find('.playlist').fadeToggle(100);
return false;
});
$this.find('.while_icon').click(function() {
if ($audio.loop) {
$(this).removeClass('active');
$audio.loop = false;
} else {
$(this).addClass('active');
$audio.loop = true;
}
return false;
});
$this.find('.rand').click(function() {
if (isrand) {
$(this).removeClass('active');
isrand = false;
} else {
$(this).addClass('active');
isrand = true;
}
return false;
});
};
return this.each(make);
};
})(jQuery);
Here is the PHP/HTML (smarty template):
<script type="text/javascript" src="/jquery.js">
</script>
<script type="text/javascript" src="/player.js">
</script>
{foreach item=pic from=$pics} {/foreach}
<table>
<tr>
<td valign="middle">
{if $pic.ext == 'yt'}
<div style=
"background-image:url('http://img.youtube.com/vi/{$pic.ytref}/0.jpg');">
<div style="height:120px; max-width:120px;">
<a alt="video no {$pic.videono}" href=
"http://www.youtube.com/v/{$pic.ytref}&fs=1&rel=0::"
title="Click to Play"><img height="120" onmouseout=
"this.src='playbtred.png'" onmouseover=
"this.src='playbty.png'" src="playbtred.png" width=
"120"></a>
</div>
</div>
<div style=
"width:60%;word-wrap: break-word;padding-bottom:20px;">
{$pic.video_descr }
</div>{elseif $pic.ext == 'mp3'}
<script type="text/javascript">
$(function(){
$('#player1').plp({
'volume': 80,
'playlist':[
{"title":"{$pic.video_descr }",
"author":"Test2",
"cover":"files/covers/1.jpg",
"mfile":"{$config.siteurl}{$pic.fullfilename}",
"duration":"330"},
]
});
});
</script><br>
<div style=
"width:60%;word-wrap: break-word;padding-bottom:20px;">
</div>{else} {include file='otheruploads.tpl'}<br>
{$pic.video_descr } {/if}
</td>
</tr>
</table>
<div class="player" id="player1">
<img alt="" class="cover" src=""><!--album cover-->
<span class="title"></span><!--song title-->
<span class="author"></span><!--artist-->
<div class="long"></div>
<div class="current">
00:00
</div>
<div class="all"></div>
<div class="volume"></div>
<div class="vol_icon"></div>
<div class="rand"></div>
<div class="while_icon"></div>
<div class="toolbar">
<div class="tlb_prev"></div>
<div class="tlb_stop"></div>
<div class="tlb_next"></div>
</div>
<div class="pl_icon active"></div>
<div class="playlist flexcroll"></div>
</div>{/if}
I'm just not sure where or how. I've literally spent the last two days searching and researching to figure it out. I'm so sure its simple, but I'm lost at the moment, and would GREATLY appreciate the help.

Knockout.js: How to sort table?

I use this example:
http://stevescodingblog.co.uk/real-time-system-resource-monitor-with-signalr-mvc-knockout-and-webapi/#comment-3293
Table displays observable array. This array is updating by clients via signalr. All works fine.
I want to add sorting by selected column.
<div id="computerInfo">
<h2>Real-time System Resource Monitor</h2>
<h5 data-bind="visible: connected">Connected to message hub</h5>
<table border="0" class="table table-striped">
<tr>
<th>Machine</th>
<th>CPU %</th>
<th>Memory Available (Mb)</th>
<th>Total Memory (Mb)</th>
<th>Mem Available %</th>
</tr>
<!-- ko foreach: machines -->
<tr data-bind="css: { highCpu: cpu() > 90 || memPercent()<30 }">
<td data-bind="text: machineName"></td>
<td data-bind="text: cpu"></td>
<td data-bind="text: memUsage"></td>
<td data-bind="text: memTotal"></td>
<td data-bind="text: memPercent"></td>
</tr>
<!-- /ko -->
</table>
$(function () {
// The view model that is bound to our view
var ViewModel = function () {
var self = this;
// Whether we're connected or not
self.connected = ko.observable(false);
// Collection of machines that are connected
self.machines = ko.observableArray();
self.headers = [
{ title: 'Machine Name', sortKey: 'keyMachineName' },
{ title: 'CPU', sortKey: 'keyCpu' },
{ title: 'Mem Usage', sortKey: 'keyMemUsage' },
{ title: 'Mem Total', sortKey: 'keyMemTotal' },
{ title: 'Mem Percent', sortKey: 'keyMemPercent' }
];
self.sort = function (header, event) {
var sortKey = header.sortKey;
//implementation of sort
};
self.sort = function (header, event) {
var sortKey = header.sortKey;
switch (sortKey) {
case 'keyMachineName':
self.machines.sort(function (a, b) {
var n = a.machineName < b.machineName ? -1 : a.machineName > b.machineName ? 1 : 0;
alert(n);
return n;//1;
});
break;
case 'keyCpu':
self.machines.sort(function (a, b) {
var n = a.cpu < b.cpu ? -1 : a.cpu > b.cpu ? 1 : 0;
alert(n);
return n;
});
break;
case 'keyMemUsage':
self.machines.sort(function (a, b) {
var n = a.memUsage < b.memUsage ? -1 : a.memUsage > b.memUsage ? 1 : 0;
alert(n);
return n;
});
break;
}
};
};
// Instantiate the viewmodel..
var vm = new ViewModel();
// .. and bind it to the view
//ko.applyBindings(vm, $("#computerInfo")[0]);
// Get a reference to our hub
var hub = $.connection.cpuInfo;
// Add a handler to receive updates from the server
hub.client.cpuInfoMessage = function (machineName, cpu, memUsage, memTotal) {
var machine = {
machineName: machineName,
cpu: cpu.toFixed(0),
memUsage: (memUsage / 1024).toFixed(2),
memTotal: (memTotal / 1024).toFixed(2),
memPercent: ((memUsage / memTotal) * 100).toFixed(1) + "%"
};
var machineModel = ko.mapping.fromJS(machine);
// Check if we already have it:
var match = ko.utils.arrayFirst(vm.machines(), function (item) {
return item.machineName() == machineName;
});
if (!match) {
vm.machines.push(machineModel);
} else {
var index = vm.machines.indexOf(match);
vm.machines.replace(vm.machines()[index], machineModel);
}
// vm.machines.sort();
//ko.applyBindings(vm, $("#computerInfo")[0]);
//$("#infoTable").tablesorter({sortList: [0,0]});
};
///
ko.applyBindings(vm, $("#computerInfo")[0]);
///
// Start the connectio
$.connection.hub.start().done(function () {
vm.connected(true);
});
});
The problem is:
sort function always returns 0, i.e. there values always the same:
var n = a.machineName < b.machineName
When I for the test return 1 then sorting works fine.
When you create a machine using
var machineModel = ko.mapping.fromJS(machine);
you create a view model with observable properties. In this case in your sort method you need to treat them as observables, so you must use them using parenthesis. For example:
case 'keyMachineName':
self.machines.sort(function (a, b) {
var n = a.machineName() < b.machineName() ? -1 : a.machineName() > b.machineName() ? 1 : 0;
alert(n);
return n;//1;
});
break;
The jQuery tablesorter plugin does not work with knockout. Simply forget it.
Knockout cannot handle when DOM nodes are moved around without its knowledge, but that's what jQuery Tablesorter does.
But knockout is perfectly prepared to sort your table for you.
Below example features
fully configurable columns, i.e. not hard-coded in the view
sortable table columns on click, including visual feedback which is the sorted column
alternating ascending/descending sort order
value formatting via a Knockout extender
automatic update of values in an interval (likely scenario in this use case)
automatic re-sort when the values update
ko.extenders.formatted = function (underlyingObservable, formatFunction) {
underlyingObservable.formatted = ko.computed(function () {
return formatFunction(underlyingObservable());
});
};
function Machine(data) {
var self = this,
memoryFormat = function (val) { return Math.round(val / 1024, 0).toLocaleString(); };
self.machineName = ko.observable().extend({formatted: function (val) { return val; }});
self.cpu = ko.observable(0).extend({formatted: function (val) { return val.toFixed(1); }});
self.memUsage = ko.observable(0).extend({formatted: memoryFormat});
self.memTotal = ko.observable(0).extend({formatted: memoryFormat});
self.memPercent = ko.computed(function () {
return self.memUsage() / self.memTotal() * 100;
}).extend({formatted: function (val) { return val.toFixed(1) + '%'; }});
self.conditions = ko.computed(function () {
return {
highCpu: self.cpu() > 50,
lowMem: self.memPercent() < 30
};
});
self.update(data);
};
Machine.prototype.update = function (data) {
ko.mapping.fromJS(data, {}, this);
};
function MachineList() {
var self = this;
self.connected = ko.observable(false);
self.machines = ko.observableArray();
self.headers = [
{title: 'Machine Name', key: 'machineName', cssClass: ''},
{title: 'CPU %', key: 'cpu', cssClass: 'right'},
{title: 'Mem Usage (MB)', key: 'memUsage', cssClass: 'right'},
{title: 'Mem Total (MB)', key: 'memTotal', cssClass: 'right'},
{title: 'Mem Available %', key: 'memPercent', cssClass: 'right'}
];
self.sortHeader = ko.observable(self.headers[0]);
self.sortDirection = ko.observable(1);
self.toggleSort = function (header) {
if (header === self.sortHeader()) {
self.sortDirection(self.sortDirection() * -1);
} else {
self.sortHeader(header);
self.sortDirection(1);
}
};
// use a computed to subscribe to both self.sortHeader() and self.sortDirection()
self.sortMachines = ko.computed(function () {
var sortHeader = self.sortHeader(),
dir = self.sortDirection(),
tempMachines = self.machines(),
prop = sortHeader ? sortHeader.key : "";
if (!prop) return;
tempMachines.sort(function (a, b) {
var va = ko.unwrap(a[prop]),
vb = ko.unwrap(b[prop]);
return va < vb ? -dir : va > vb ? dir : 0;
});
self.machines.notifySubscribers();
});
self.insertMachine = function (data) {
var machine = ko.utils.arrayFirst(vm.machines(), function (item) {
return ko.unwrap(item.machineName) == ko.unwrap(data.machineName);
});
if (machine) machine.update(data);
else vm.machines.push(new Machine(data));
self.sortMachines();
};
};
// -------------------------------------------------------------------------------
// connection mockup
$.connection = {
cpuInfo: {client: {}},
hub: {start: function() { return $.Deferred().resolve(); }}
};
var vm = new MachineList(),
hub = $.connection.cpuInfo;
hub.client.cpuInfoMessage = function (data) { vm.insertMachine(data); };
// start the connection as soon as possible...
$.connection.hub.start().done(function () {
vm.connected(true);
$(function () {
// ...but don't apply bindings before the document is ready
ko.applyBindings(vm, $("#computerInfo")[0]);
});
// create some random sample data
setInterval(function () {
var GB = 1024 * 1024;
['A', 'B', 'C', 'D'].forEach(function (name) {
hub.client.cpuInfoMessage({
machineName: name,
cpu: getRandomInt(0, 1000) / 10,
memUsage: getRandomInt(5 * GB, 7 * GB),
memTotal: 10 * GB
});
});
}, 1000);
});
// -------------------------------------------------------------------------------
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
.table { border-collapse: collapse; }
.table th, .table td { border: 1px solid silver; padding: 0 2px; }
.sortable { cursor: pointer; }
.table-striped tbody tr:nth-child(odd) { background-color: #f7f7f7; }
.highCpu { color: red; }
.lowMem { color: red; }
.right { text-align: right; }
.sorted { background-color: #B5E0FF; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<div id="computerInfo">
<h2>Real-time System Resource Monitor</h2>
<h5 data-bind="visible: connected">Connected to message hub</h5>
<table border="0" class="table table-striped">
<thead>
<tr data-bind="foreach: headers">
<th class="sortable" data-bind="click: $root.toggleSort, text: title, css: {sorted: $data === $root.sortHeader()}"></th>
</tr>
</thead>
<tbody data-bind="foreach: machines">
<tr data-bind="foreach: $root.headers, css: conditions">
<td data-bind="text: $parent[key].formatted, css: cssClass"></td>
</tr>
</tbody>
</table>
</div>

wookmark modification and li side by side and under each other

i'm using wookmark plugin for my project and i need to load more items when the V scroll reach to the bottom.
plugin url : http://www.wookmark.com/jquery-plugin
scroll function that i use :
function _scroll() {
var v = false;
$(document).scroll(function(e) {
var t = document.height - (window.pageYOffset + window.innerHeight);
if ((t <= 20) && ( !v)) {
v = true;
$.ajax({ type:"POST",
data: {type:$("#type").val(),id:$("#pid").val(),lid:$("#lid").val()},
async:true,
cache:false,
url:"fetchMore.php?v=18",
success: function(d) {
var t = d.split('{#}');
if (parseInt($("#lid").val()) != t[1]) {
$("#tiles").append(t[0]);
$("#lid").val(t[1]);
applyLayout();
}
v = false;
} });
}
});
}
and the applylayout function:
function applyLayout() {
$('#tiles').imagesLoaded(function() {
// Destroy the old handler
if ($handler.wookmarkInstance) {
$handler.wookmarkInstance.clear();
}
$handler = $('#tiles li');
$handler.wookmark(options);
});
}
Finally my options and sort functions:
function comparatorId(a, b) {
return $(a).attr("id") > $(b).attr("id") ? -1 : 1;
}
function _Animate() {
$('#tiles').imagesLoaded(function() {
options = {
autoResize: true,
container: $('#main'),
offset: 2,
itemWidth: 210,
comparator: comparatorId,
direction: 'right',
fillEmptySpace: false
};
$handler = $('#tiles li');
$handler.wookmark(options);
});
}
The problem is:
when i'm going to load more the items are randomly re-sorting just like there is no comparatorId function ..
is there any solution ?
if there is no solution ..
how can i do a ul li tags like this layout ?
i can put them side by side but i want them to be side by side + under each other
i've solved the problem..
it's just by putting data-id="{ID}" tag for li and remove all class(es)

Moving repeating pattern in a div container

I have a div container which has a repeating background image that forms a pattern, and I would like to animate it with jQuery so that the pattern moves south-west.
How can this be done?
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="content/main.css">
<script src="content/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#container").animate({
'background-position': '1110px 1110px'
}, 1000, function () {
});
});
</script>
</head>
<body>
<div id="container">
</div>
</body>
Have a look at Sprightly. It's a jQuery plugin and makes animating background images reasonably easy.
To pan (animate a background image), the documentation gives this code as an example:
$('#trees').pan({fps: 30, speed: 2, dir: 'left'});
If you're looking for a simpler, lighter approach, this plugin may be a better solution. To animate a background, give it an offset:
$('.elem').animate({backgroundPosition: '500px 150px'})
Like this:
$("#container").animate({
'background-position': '1110px 1110px'
}, 1000, function () {
});
...
/**
* #author Alexander Farkas
* v. 1.22
*/
(function ($) {
if (!document.defaultView || !document.defaultView.getComputedStyle) { // IE6-IE8
var oldCurCSS = $.curCSS;
$.curCSS = function (elem, name, force) {
if (name === 'background-position') {
name = 'backgroundPosition';
}
if (name !== 'backgroundPosition' || !elem.currentStyle || elem.currentStyle[name]) {
return oldCurCSS.apply(this, arguments);
}
var style = elem.style;
if (!force && style && style[name]) {
return style[name];
}
return oldCurCSS(elem, 'backgroundPositionX', force) + ' ' + oldCurCSS(elem, 'backgroundPositionY', force);
};
}
var oldAnim = $.fn.animate;
$.fn.animate = function (prop) {
if ('background-position' in prop) {
prop.backgroundPosition = prop['background-position'];
delete prop['background-position'];
}
if ('backgroundPosition' in prop) {
prop.backgroundPosition = '(' + prop.backgroundPosition;
}
return oldAnim.apply(this, arguments);
};
function toArray(strg) {
strg = strg.replace(/left|top/g, '0px');
strg = strg.replace(/right|bottom/g, '100%');
strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g, "$1px$2");
var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
return [parseFloat(res[1], 10), res[2], parseFloat(res[3], 10), res[4]];
}
$.fx.step.backgroundPosition = function (fx) {
if (!fx.bgPosReady) {
var start = $.curCSS(fx.elem, 'backgroundPosition');
if (!start) {//FF2 no inline-style fallback
start = '0px 0px';
}
start = toArray(start);
fx.start = [start[0], start[2]];
var end = toArray(fx.end);
fx.end = [end[0], end[2]];
fx.unit = [end[1], end[3]];
fx.bgPosReady = true;
}
//return;
var nowPosX = [];
nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
fx.elem.style.backgroundPosition = nowPosX[0] + ' ' + nowPosX[1];
};
})(jQuery);

Categories

Resources