Passing JS variable value to PHP variable to update database - javascript

If you want to see the part where I tried AJAX, go look down below. It completely messed up the page and I'm stuck on how to do this. I've got some code here:
$id = $_SESSION["id"];
$sql = "SELECT riskcoin FROM klanten WHERE id='$id'";
$INFO=mysqli_query($conn, $sql);
if (mysqli_num_rows($INFO) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($INFO)) {
echo "riskcoin: " . $row["riskcoin"]. "<br>";
$riskcoins = $row["riskcoin"];
}
} else {
echo "0 results";
}
?>
var dealerHand = [];
var playerHand = [];
var currentHand;
var deck;
var deckCount;
var countCards = true;
var bets = new Bets();
// Bets Object
function Bets() {
this.pot = <?php echo "$riskcoins"; ?>;
this.bet = 0;
$('#bet').text(0);
$('#pot').text('$' + this.pot);
}
// Bets methods
Bets.prototype.updateAmounts = function () {
$('#bet').text('$' + this.bet);
$('#pot').text('$' + this.pot);
};
Bets.prototype.doubleDown = function() {
this.pot -= this.bet;
this.bet += this.bet;
};
Bets.prototype.potAmount = function() {
return this.pot;
};
Bets.prototype.betAmount = function(){
return this.bet;
};
Bets.prototype.disableDeal = function () {
$('#button-deal').addClass('disabled');
};
Bets.prototype.addBet = function(amount) {
if (this.pot >= amount) {
this.pot = this.pot - amount;
this.bet = this.bet + amount;
this.updateAmounts();
$('#button-deal').removeClass('disabled');
} else {
notEnoughChips();
}
};
First part is php second part js. I have an int value in my database called riskcoin. this.pot contains that riskcoin value (//Bets object) and shows itin another php file in a paragraph with id="pot".
When an image is clicked another function ads an amount to the bet depending on the picture (for example 5).
Now my question: after the line this.updateAmounts(); it executes
// Bets methods
Bets.prototype.updateAmounts = function () {
$('#bet').text('$' + this.bet);
$('#pot').text('$' + this.pot);
Now my question would be if I could update the riskcoin value in my database with an update query after this function with the current this.pot value? It should show live updates without page refreshes. I've read about AJAX so I tried something like this:
Bets.prototype.updateAmounts = function () {
$('#bet').text('$' + this.bet);
$('#pot').text('$' + this.pot);
window.history.pushState('page2', 'Title', '?coins=' + this.pot);
$(document).ready(function(){
var url = window.location.href;
var params = url.split('?coins=');
var id = (params[1]);
$("#button-deal").click(function(){ $.ajax({
type:"POST",
url:"blackjackgame.php",
data:{id:id},
success:function(result){
$("#pot").html(result);
}
});
});
});
};
But it for some reason when I click on the deal button (#button-deal) it shows up my login page in the middle of the page under all the other stuff, console gives me: GET http://riskybusiness.nglyceum.eu/games/login.css net::ERR_ABORTED 404 (Not Found)jquery-3.1.1.js:5921

PHP and Javascript execute in different contexts. PHP on the server, Javascript on the client (browser). Keep your PHP code and Javascript separate. Since PHP executes first on the server, you can embed PHP output into your HTML/Javascript/CSS—BEFORE—it is sent to the browser.
One problem you have with your code is intermingling PHP and Javascript, such as:
<?php
if (mysqli_num_rows($INFO) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($INFO)) {
echo "riskcoin: " . $row["riskcoin"]. "<br>";
$riskcoins = $row["riskcoin"];
}
} else {
echo "0 results";
}
?>
var dealerHand = [];
var playerHand = [];
var currentHand;
// Bets Object
function Bets() {
this.pot = <?php echo "$riskcoins"; ?>;
this.bet = 0;
$('#bet').text(0);
$('#pot').text('$' + this.pot);
}
The PHP (only) gets processed on the server, and this text is sent to the client:
riskcoin: 100<br>
var dealerHand = [];
var playerHand = [];
var currentHand;
// Bets Object
function Bets() {
this.pot = 100;
this.bet = 0;
$('#bet').text(0);
$('#pot').text('$' + this.pot);
}
Also, this $("#button-deal").click(function(){ in your code adds a click event handler to your button. The problem is, you're not adding this event handler until addBet() is executed, which then executes updateAmount(). Not only don't wait, but the handler is added each time addBet() is executed. Instead add the event handler on page load.
I've separated the various code components into server-side execution and client-side execution contexts, and properly connected them to each other:
var dealerHand = [];
var playerHand = [];
var currentHand;
var deck;
var deckCount;
var countCards = true;
var bets = new Bets();
// Bets Object
function Bets() {
this.pot = 100; // <?=$riskcoin?>;
this.bet = 0;
$('#bet span').text('$' + 0);
$('#pot span').text('$' + this.pot);
$('#deal button').addClass('disabled');
}
// Bets methods
Bets.prototype.updateAmounts = function() {
$('#bet span').text('$' + this.bet);
$('#pot span').text('$' + this.pot);
};
Bets.prototype.potAmount = function() {
return this.pot;
};
Bets.prototype.betAmount = function(){
return this.bet;
};
Bets.prototype.addBet = function(amount) {
if (this.pot >= amount) {
this.pot = this.pot - amount;
this.bet = this.bet + amount;
this.updateAmounts();
$('#deal button').removeClass('disabled');
} else {
notEnoughChips();
}
};
// add the click event handler on page load
document.querySelector("#deal button").addEventListener("click", evt => {
$.ajax({
type: "POST",
url: "deal.php", // <-- post data to separate PHP file, see PHP file below
data: {bet: bets.betAmount()},
success: function(result) {
const win = (result > bets.pot)? " (won)": " (lost)";
bets.pot = result;
bets.bet = 0;
$("#pot span").text('$' + bets.pot + win);
$('#bet span').text('$' + bets.bet);
$('#deal button').addClass('disabled');
}
});
});
document.querySelectorAll("#bet button").forEach(btn => {
btn.addEventListener("click", evt => {
bets.addBet(parseInt(evt.target.textContent));
});
});
function notEnoughChips() {
alert("Not enough chips.");
}
// mock ajax, remove in real world
$.ajax = (function () {
return function (params) {
if (Math.random() < 0.5) {
params.success(bets.pot + (params.data.bet * 2));
} else {
params.success(bets.pot);
}
};
}());
.disabled {
cursor: not-allowed;
pointer-events: none;
color: #c0c0c0;
background-color: #ffffff;
}
<!-- uncomment in the real world
<?php
$id = $_SESSION["id"];
$sql = "SELECT riskcoin FROM klanten WHERE id=?"; // <-- use prepared statements
$INFO=mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, "i", $id);
mysqli_stmt_execute($stmt);
if (mysqli_num_rows($INFO) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($INFO)) {
$riskcoin = $row["riskcoin"];
}
} else {
$riskcoin = 0;
}
?>
-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="pot">Pot: <span><?=$riskcoin?></span></div>
<div id="bet">Bet: <span>0</span> <button>+5</button><button>+10</button><button>+15</button><button>+20</button></div>
<div id="deal"><button>Deal</button></div>
deal.php (The JQuery ajax function POSTs to this file.)
<?php
// this file called in JQuery ajax function found in "#deal button" "click" handler
$id = $_SESSION["id"];
$bet = $_POST["bet"];
$sql = "SELECT riskcoin FROM klanten WHERE id= ?";
$INFO=mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, "i", $id);
mysqli_stmt_execute($stmt);
if (mysqli_num_rows($INFO) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($INFO)) {
$riskcoin = $row["riskcoin"];
}
} else {
$riskcoin = 0;
}
// random win or lose
$riskcoin += ((bool)random_int(0, 1))? ($bet * 2): (-1 * abs($bet));
$sql = "UPDATE klanten SET riskcoin = ? WHERE id = ?";
$INFO=mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, "ii", $riskcoin, $id);
mysqli_stmt_execute($stmt);
echo $riskcoin;
?>

// Bets Object
function Bets() {
this.pot = <?php echo "$riskcoins"; ?>;
this.bet = 0;
$('#bet').text(0);
$('#pot').text('$' + this.pot);
}
You cannot put php code inside of javascript as PHP is server side so it runs before javascript.
I believe your best option would be to use php for all of it.

Related

setInterval for jQuery for loop trouble

I am trying to run a specific for loop every x seconds, but cannot seem to make `setInterval work. I am sure my syntax is incorrect, yet, I cannot seem to get it right.
I have added my full code below:
jQuery:
//Click saves this.id as userID
$(function() {
var rTitle, rText, qTitle, qText, numRows, userID;
$("#buttons").find(".btn").click(function() {
$(this).parent().toggleClass('fullscreen');
$(this).parent().siblings().toggleClass('master');
var userID = this.id;
//userID is then used for ajax to PHP script, information passed back is put in variables and generateProblems function is run
$.ajax({
type: "POST",
url: 'include/responseget.php',
dataType: 'json',
data: {
userID: userID
},
success: function(json) {
rTitle = json.rTitle;
rText = json.rText;
qTitle = json.qTitle;
qText = json.qText;
next = json.next;
numRows = json.numRows;
id = json.id;
generateProblems();
}
});
});
//Generate draggable html with an interval of 1000
function generateProblems() {
$('<div>' + qTitle + '</div>').data('number', qTitle).attr('id', 'question').attr('class', 'bold').appendTo($("#" + id).parent()).hide().fadeIn(2000);
for (var i = 0; i < numRows; i++) {
setInterval(function() {
$('<div>' + rTitle[i] + '</div>').data('number', next[i]).attr('id', +next[i]).appendTo($("#" + id).parent()).draggable({
containment: '.site-wrapper',
stack: '#testpile div',
cursor: 'move',
revert: true
}).hide().fadeIn(2000)
$('<div>' + rText[i] + '</div>').data('number', next[i]).attr('id', +next[i]).appendTo($("#" + id).parent()).hide().fadeIn(2000);
}, 1000);
}
//Rest of the code is not important, but I put it in nonetheless.
$('#testdrop').droppable({
drop: handleDropEvent,
accept: '#testpile div'
});
function handleDropEvent(event, ui) {
var problemNumber = ui.draggable.data('number');
ui.draggable.draggable('disable');
ui.draggable.draggable('option', 'revert', false);
$("#testpile").children().hide();
$.ajax({
type: "POST",
url: 'include/responseget.php',
dataType: 'json',
data: {
userID: problemNumber
},
success: function(json) {
rTitle = json.rTitle;
rText = json.rText;
qTitle = json.qTitle;
qText = json.qText;
next = json.next;
numRows = json.numRows;
generateProblems();
}
});
}
}
});
PHP:
<?php include 'login.php';
if(isset($_POST['userID'])){
$id = $_POST['userID'];
$stmt = $conn->prepare("SELECT DISTINCT AnswerTitle, AnswerText, QuestionTitle, QuestionText, Next FROM question_answers
INNER JOIN question
ON question_answers.QuestionID=question.QuestionID
INNER JOIN answer
ON question_answers.AnswerID=answer.AnswerID
WHERE AnswerGroup = ?;");
$stmt->bind_param('s', $id);
$stmt->execute();
$result = $stmt->get_result();
while($row = $result->fetch_assoc())
{
$rTitle_array[] = $row['AnswerTitle'];
$rText_array[] = $row['AnswerText'];
$qTitle = $row['QuestionTitle'];
$qText = $row['QuestionText'];
$next_array[] = $row['Next'];
$numRows = ($result->num_rows);
}
$response = array(
'rTitle' => $rTitle_array,
'rText' => $rText_array,
'qTitle' => $qTitle,
'qText' => $qText,
'next' => $next_array,
'numRows' => $numRows,
'id' => $id
);
echo json_encode($response);
}
// close connection
mysqli_close($conn);
?>
It sounds like you're trying to get this effect of adding one row every second. You could use recursion.
Also, setInterval is for numerous calls. setTimeout is for a single call.
function generateProblems(i)
{
// if we're at the end then stop
if(i == numRows) return;
// wait 1000
setTimeout(function()
{
// do what you want with i here
// call the next iteration
generateProblems(i + 1);
}, 1000);
}
// then you kick it off with the 0 index
generateProblems(0);
Or if you want the first iteration to kick off immediately:
function generateProblems()
{
// if we're at the end then stop
if(i == numRows) return;
// do what you want with i here
// move to next row
++i;
setTimeout(generateProblems, 1000);
}
// global var to keep track of where we are
i = 0;
generateProblems

$.post to PHP file - callback not being hit till containing loop finished?

I'm making a stock table, where the user can input a number of stock to issue out, and this function is to verify, for each member of the table, whether or not the quantity of stock in the database is sufficient to make the issue.
When I breakpoint through the code on Chrome, it seems to never hit the inside code of the $.post until after its finished looping through the table. And by then the data that is supposed to be passed to AddIssue just becomes 1 and 10 and nothing else.
It's starting to drive me mad, so I'd appreciate a pointer on what I'm doing wrong here
var issueArray =[];
function VerifyIssue()
{
var numRows = document.getElementById("searchTable").rows.length - 2;
var running = true;
var str1 = "issue_";
while(running == true)
{
if (numRows < 0 && running == true)
{
running = false;
//insert code for success
break;
}
else if (running == false)
{
break;
}
var str2 = numRows;
var comb = str1.concat(str2);
var issue_element = document.getElementById(comb);
var q = issue_element.value;
var i = issue_element.name;
var idd = i.replace("issue_", "");
var trimId = idd.trim();
$.post
(
'includes/issueCheck.php',
{
id: trimId,
issueQuantity: q
},
function(result)
{
alert(result);
if (result < 0)
{
alert("One of more quantities inputted are greater than held in stock");
running = false;
}
if (result > 0)
{
addIssue(trimId, q);
}
}
);
numRows = numRows - 1;
}
alert(issueArray);
}
function addIssue(issueID, quant)
{
var item = {};
item.label = issueID;
item.value = quant;
issueArray.push(item);
}
This is the PHP that is called by the $.post
<?php
$server = 'SQL2008';
$connectionInfo = array( "Database"=>"rde_470585");
$conn = sqlsrv_connect($server,$connectionInfo);
$false = -1;
$true = 1;
$id = $_POST['id'];
$quantity = $_POST['issueQuantity'];
$query = "Select Quantity FROM Stock WHERE StockID = ?";
$param = array($id);
$res = sqlsrv_query($conn, $query, $param);
$row = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC);
$dbQuantity = $row['Quantity'];
if ($dbQuantity < $quantity)
{
echo $false;
}
else if($dbQuantity >= $quantity)
{
echo $true;
}
Do you realise that your function(result){ ... } will only be called when the server response for your POST request is received? You have to build the code to take that delay into account.
I'm still working on this, reading up on Promises based on what #jojo said, but not sure if it's going to work for me.
How else can I make the javascript wait for a server response before resuming?

Passing the query count in javascript variable

See i have below Code in my javascript
var itemCount = 5, activeScroll = 0, countScroll = 0;
setInterval(function() {
if(countScroll == (itemCount - 2))
{
activeScroll = 0;
countScroll = 0;
$('#list').animate({scrollTop: 0});
}
else
{
activeScroll += 250;
countScroll += 1;
$('#list').animate({scrollTop: activeScroll});
}
}, 2000);
and my query string in php code is
$userads = mysql_query("SELECT * FROM user_ads ORDER BY `user_addate` DESC");
$adcount = mysql_num_rows($userads);
i am trying to assign value of $adcount in javascript variable var itemCount;
query is running in test.php and javascript is scroller.js.
Please help me .
You can output javascript by test.php:
<?php
$userads = mysql_query("SELECT * FROM user_ads ORDER BY `user_addate` DESC");
$adcount = mysql_num_rows($userads);
?>
<script type='text/javascript'>
var itemCount = <?php echo $adcount; ?>;
setupTimer(itemCount);
</script>
Make sure the scroller.js defines the function setupTimer(itemCount) that performs the task you want, instead of firing right away.
First you need to request the value from the server. Then you can assign it.
var itemCount;
setInterval(function() {
$.get('test.php', function(response) {
itemCount = response.itemCount;
// you scroll logic here
}, 'json');
}, 2000);
In test.php you should output the value by something like this:
$output = array(
"itemCount" => $adcount
);
print json_encode($output);
in scroller.js type this code:
$.ajax("test.php", {
type: 'post',
data: {
count:itemCount
},
sync: true,
success: function (adcount) {
itemCount=adcount;
}
});
in test.phptype this code:
if (isset($_POST['count']))
{
echo $adcount;
exit;
}
notice:you should use jquery file in your script for ajax

Splitting an AJAX call which returns 5000 rows into multiple AJAX calls with 100 rows

I have a ajax call, and I am loading the data returned into a datatable
Here is my jquery ajax call
<script type="text/javascript">
var oTable;
$(document).ready(function() {
window.prettyPrint() && prettyPrint();
$('#load').click(function()
{
var v = $('#drp_v').val();
var cnt = $('#drp_cnt').val();
var ctg = $('#drp_ctg').val();
var api = $('#drp_api').val();
var nt = $('#drp_nt').val();
$.post("ajax.php",
{ 'version':v,'category':ctg,
'country':cnt,'network_id':nt,
'api':api,'func':'show_datatable'},
function(data)
{
var aColumns = [];
var columns = [];
for(var i = 0; i < data.length; i++)
{
if(i>0)
break;
keycolumns = Object.keys(data[i]);
for(j = 0; j < keycolumns.length; j++)
{
if($.inArray(keycolumns[j],aColumns.sTitle)<=0)
{
aColumns.push({sTitle: keycolumns[j]}) //Checks if
columns.push(keycolumns[j]) //Checks if
}
}
}
var oTable = $('#jsontable').dataTable({
"columns":aColumns,
"sDom": 'T<"clear">lfrtip',
"oTableTools": {
"aButtons": [
{
"sExtends": "csv",
"sButtonText": "CSV",
}
]
}
});
oTable.fnClearTable();
var row = []
for(var i = 0; i < data.length; i++)
{
for(var c = 0; c < columns.length; c++)
{
row.push( data[i][columns[c]] ) ;
}
oTable.fnAddData(row);
row = [];
}
},'json');
});
});
</script>
And here's my php function
function show_datatable($version,$ctg,$cnt,$nt,$api)
{
$cnt_table = "aw_countries_".$version;
$ctg_table = "aw_categories_".$version;
$off_table = "aw_offers_".$version;
$sizeof_ctg = count($ctg);
$cond_ctg = " ( ";
for($c = 0; $c < $sizeof_ctg ; $c++)
{
$cond_ctg = $cond_ctg." $ctg_table.category = '".$ctg[$c]."' ";
if($c < intval($sizeof_ctg-1))
$cond_ctg = $cond_ctg." OR ";
else if($c == intval($sizeof_ctg-1))
$cond_ctg = $cond_ctg." ) ";
}
$sizeof_cnt = count($cnt);
$cond_cnt = " ( ";
for($cn = 0; $cn < $sizeof_cnt ; $cn++)
{
$cond_cnt = $cond_cnt." $cnt_table.country = '".$cnt[$cn]."' ";
if($cn < intval($sizeof_cnt-1))
$cond_cnt = $cond_cnt." OR ";
else if($cn == intval($sizeof_cnt-1))
$cond_cnt = $cond_cnt." ) ";
}
$sizeof_nt = count($nt);
$cond_nt = " ( ";
for($n = 0; $n < $sizeof_nt ; $n++)
{
$cond_nt = $cond_nt." $off_table.network_id = '".$nt[$n]."' ";
if($n < intval($sizeof_nt-1))
$cond_nt = $cond_nt." OR ";
else if($n == intval($sizeof_nt-1))
$cond_nt = $cond_nt." ) ";
}
$sizeof_api = count($api);
$cond_api = " ( ";
for($a = 0; $a < $sizeof_api ; $a++)
{
$cond_api = $cond_api." $off_table.api_key = '".$api[$a]."' ";
if($a < intval($sizeof_api-1))
$cond_api = $cond_api." OR ";
else if($a == intval($sizeof_api-1))
$cond_api = $cond_api." ) ";
}
$output = "";
$sql = "SELECT *
FROM $off_table,$cnt_table,$ctg_table
WHERE $off_table.id = $cnt_table.id
AND $off_table.id = $ctg_table.id
AND ".$cond_api."
AND ".$cond_nt."
AND ".$cond_cnt."
AND ".$cond_ctg;
$result = mysql_query($sql);
$arr_result = array();
while($row = mysql_fetch_assoc($result))
{
$arr_result[] = $row;
}
$arr_result_enc = json_encode($arr_result);
echo $arr_result_enc;
}
Now, I want to modify this code. Say I want to work it like this:
I will call for v, and the AJAX will send me 100 rows once, then again 100 rows and then again 100 rows.
I mean splitting the AJAX call to returns chunks of all the data one after another. Say something like there will be multiple times when the AJAX will be called, and each time it will send me 100 chunks of data.
While the work will be going on, there will be a progress bar with a cancel button.
If I click the cancel button, then if 3 times the AJAX function have been called, it will show me 300 data and then the AJAX will be stopped. The database will show only 300 data.
JQ:
// counter that allows you to get a new set of rows
var step = 0;
// set variable if you want to restrict the number of rows will be loaded
var maxStep = 0;//
// how many rows should be returned
var count = 100;
// if the cancel button is pressed
var cancel = false;
$(function() {
$('#load').click(function(){
getData();
})
$('#cancel').click(function(){
cancel = true;
})
});
function getData()
{
step++;
//If cancel variable is set to true stop new calls
if(cancel == true) return;
// checks if the variable is set and limits how many rows to be fetched
if(maxStep >0 and step >= maxStep) return;
$.post('ajax.php'
,{
'step':step,
'count':count,
}
,function(data, textStatus, jqXHR){
// do something with the data
// when it finishes processing the data, call back function
getData();
}
,'json'
)
}
AJAX.PHP
$step = 0;
if(isset($_POST['step'])) $step = (int)$_POST['step'];
$count = 0;
if(isset($_POST['count'])) $count = (int)$_POST['count'];
if($step>0 and $count>0)
{
$offset = ($step-1) * $count;
$limit = $offset.','.$count;
// --------------
// your code here
// --------------
$sql = "SELECT *
FROM $off_table,$cnt_table,$ctg_table
WHERE $off_table.id = $cnt_table.id
AND $off_table.id = $ctg_table.id
AND ".$cond_api."
AND ".$cond_nt."
AND ".$cond_cnt."
AND ".$cond_ctg."
LIMIT ".$limit;// <- limit
$result = mysql_query($sql);
$arr_result = array();
while($row = mysql_fetch_assoc($result))
{
$arr_result[] = $row;
}
$arr_result_enc = json_encode($arr_result);
echo $arr_result_enc;
// echo rows
echo json_encode($rows);
}
Here's a heavy refactoring of the client-side code, in which the overall process is split into into three separate functions getBatch(), makeRows() and showData(), and kicked off by a very modified version of the original click handler.
Batching is controlled by getBatch(), which makes a ajax requests with two extra params - start and batchSize. These instruct the server-side script which batch of data to return.
makeRows() and showData() are just synchronous worker functions called by getBatch().
I have assumed that progress is reported in a DOM element "#progress"`. You can report what you like here. I've kept it simple, showing the accumulated row count. By adding a batch counter, you could also show the number of completed batches.
Cancellation is achieved by setting outer var allowBatch to false. The currently requested batch will continue to be found but permission to retrieve further batches is withdrawn.
For good measure various DOM elements are enabled/disabled or shown/hidden at the start and end of the process. This can be omitted if not required.
var oTable;
$(document).ready(function() {
window.prettyPrint() && prettyPrint();
var aColumns = [],
columns = [],
rows = [],
$progress = $("#progress"),
allowBatch;
function getBatch(options) {
return $.post("ajax.php", options, 'json').then(function(data) {
var promise;
if(allowBatch && data && data.length) {
$progress.text(makeRows(data));
options.start += batchsize;
promise = getBatch(options);
} else {
promise = $.when(showData());
}
return promise;
});
}
function makeRows(data) {
var keycolumns, i, j;
if(aColumns.length == 0) {
keycolumns = Object.keys(data[0]);
for(j = 0; j < keycolumns.length; j++) {
if($.inArray(keycolumns[j], aColumns.sTitle) <= 0) {
aColumns.push({sTitle: keycolumns[j]});
columns.push(keycolumns[j]);
}
}
}
for(i = 0; i < data.length; i++) {
rows.push( columns.map(function(col) {
return data[i][col];
}) );
}
return rows.length;
}
function showData() {
var oTable = $('#jsontable').dataTable({
'columns': aColumns,
'sDom': 'T<"clear">lfrtip',
'oTableTools': {
"aButtons": [{
"sExtends": "csv",
"sButtonText": "CSV"
}]
}
});
oTable.fnClearTable();
$.each(rows, function(row) {
oTable.fnAddData(row);
});
return oTable;
}
$('#load').on('click', function(e) {
e.preventDefault();
var $load = $(this).attr('disabled', true),
$cancel = $("#cancel").show();
$progress.text('').show();
aColumns.length = columns.length = rows.length = 0;
allowBatch = true;
getBatch({
'version': $('#drp_v').val(),
'category': $('#drp_ctg').val(),
'country': $('#drp_cnt').val(),
'network_id': $('#drp_nt').val(),
'api': $('#drp_api').val(),
'func': 'show_datatable',
'start': 0,
'batchsize': 100
}).then(function(oTable) {
// ... all done
$load.attr('disabled', false);
$cancel.hide();
$progress.hide();
});
});
$("#cancel").on('click', function(e) {
e.preventDefault();
allowBatch = false;
}).hide();
$("#progress").hide();
});
Tested only for parse errors, so may need to be debugged
You will still need to modify the server-side script to accept the two additional parameter start and batchsize and compose its SQL accordingly. That should be fairly trivial.
The part I'm most uncertain about is makeRows(), which I struggled with slightly. If nothing works, look there first.

Any JavaScript parser for .lrc?

I was using the code from Kejun's Blog .
I want to parse a .lrc (which is basically a lyrics file) so as to get the time variable as well as the string(read lyrics) . I tried out this code and could not seem to get the output .
<html>
<head>
<script src="jquery-1.7.1.js"></script>
<script>
$(document).ready(function () {
$.ajax({
type: "GET",
url: "a.txt",
dataType: "text",
success: function (data) {
parseLyric(data);
}
});
});
var _current_lyric = new Array();
function convertLRCLyric(inf) {
inf += "n";
var lyric = inf.match(/([(d{2}:d{2}(.d{1,2}){0,1})]){1,}W*n|([(d{2}:d{2}:d{2}(.d{1,2}){0,1})]){1,}W*n/ig);
var l_s = '',
l_tt, l_ww, l_i, l_ii;
if (!lyric || !lyric.length) {
return;
}
for (l_i = 0; l_i < lyric.length; l_i++) {
l_tt = lyric[l_i].match(/([d{2}:d{2}(.d{1,2}){0,1}])|([d{2}:d{2}:d{2}(.d{1,2}){0,1}])/ig);
l_ww = lyric[l_i].replace(/[S+]/ig, '').replace(/n{1,}/ig, '');
for (l_ii = 0; l_ii < l_tt.length; l_ii++) {
l_tt[l_ii] = l_tt[l_ii].replace(/[/,'').replace(/]/, '');
if (l_tt[l_ii].search(/d{2}:d{2}:d{2}.d{2}/g) >= 0) {
_current_lyric[l_tt[l_ii].substring(0, l_tt[l_ii].length - 1)] = l_ww;
} else if (l_tt[l_ii].search(/d{2}:d{2}:d{2}.d{1}/g) >= 0) {
_current_lyric[l_tt[l_ii]] = l_ww;
} else if (l_tt[l_ii].search(/d{2}:d{2}:d{2}/g) >= 0) {
_current_lyric[l_tt[l_ii] + ".0"] = l_ww;
} else if (l_tt[l_ii].search(/d{2}:d{2}.d{2}/g) >= 0) {
_current_lyric["00:" + l_tt[l_ii].substring(0, l_tt[l_ii].length - 1)] = l_ww;
} else if (l_tt[l_ii].search(/d{2}:d{2}.d{1}/g) >= 0) {
_current_lyric["00:" + l_tt[l_ii]] = l_ww;
} else if (l_tt[l_ii].search(/d{2}:d{2}/g) >= 0) {
_current_lyric["00:" + l_tt[l_ii] + ".0"] = l_ww;
}
}
}
}
function parseLyric(allText) {
_current_lyric = [];
convertLRCLyric(allText);
var ly = "";
for (var time in _current_lyric) {
ly += time + "--" + _current_lyric[time] + "n";
}
alert(ly);
}
</script>
</head>
<body>
</body>
</html>
But i keep getting a blank alert . Any help would be great . Thanks in advance .
Answer :
Ok so i built my own parser ,Here is the code
var contents = " " ;
function readMultipleFiles(evt) {
//Retrieve all the files from the FileList object
var files = evt.target.files;
if (files) {
for (var i = 0, f; f = files[i]; i++) {
var r = new FileReader();
r.onload = (function (f) {
return function (e) {
contents = e.target.result;
processData(contents);
};
})(f);
r.readAsText(f);
}
} else {
alert("Failed to load files");
}
}
document.getElementById('fileinput').addEventListener('change', readMultipleFiles, false);
var allTextLines = " ";
var lyrics = [];
var tim = [] ;
var line = " ";
// parsing the Lyrics
function processData(allText) { // This will only divide with respect to new lines
allTextLines = allText.split(/\r\n|\n/);
next();
}
function next()
{
for (i=0;i<allTextLines.length;i++)
{
if (allTextLines[i].search(/^(\[)(\d*)(:)(.*)(\])(.*)/i)>=0 )// any line without the prescribed format wont enter this loop
{
line = allTextLines[i].match(/^(\[)(\d*)(:)(.*)(\])(.*)/i);
tim[i] = (parseInt(line[2])*60)+ parseInt(line[4]); // will give seconds
lyrics[i]= line[6] ;//will give lyrics
}
}
}
Code php : with format
public function get_lrc_song($song) {
$lyrics_file = $song ['lyrics_file'];
$json = curlClass::getInstance ( true )->fetchURL ( $lyrics_file );
$content = explode ( "\n", $json );
$regix = "$\][^>]+$";
$result = "";
foreach ( $content as $item ) {
$isHas = preg_match ( $regix, $item, $data );
$dt = str_replace ( "]", "", $data[0] );
if ($dt != ""){
$result .= $dt . "\n";
}
}
echo $result;
}
I've made an plugin related to this which you can find here
There is an tutorial on how to use this and also i think this is most probably the simplest one I've seen while researching about this topic.
there is another lrc-parser for this purpose, I've tried it but, it lack some features like playing on command and other necessary features.
So i made them all
the code looks like this:
//view the tutorial of this usage on https://multimentality.000webhostapp.com/others
var lyricPlayer = {
"set_divval":function(){var all_lyrics = "";var mose;if(lyricPlayer.Mode=="Long"){mose="block"}else if(lyricPlayer.Mode=="Line"){mose="none"}else{alert("mode property: undefined value. lyricPlayer.Mode has two values 'Long' and 'Line'");mose="block"}for(let y=lyricPlayer.countt;y<lyricPlayer.lyrics.length;y++){all_lyrics+=`<span id='lyricsItem_${lyricPlayer.tim[y]}' class='lyricsItem_class' style='display:${mose};'>${lyricPlayer.lyrics[y]}</span>`;lyricPlayer.tmp_count=lyricPlayer.countt;lyricPlayer.main_dict[lyricPlayer.tim[y]]=lyricPlayer.tmp_count;lyricPlayer.tmp_count++;}document.getElementById('lyrics_playerMain').innerHTML=all_lyrics;},
"processData":function(allText){lyricPlayer.allTextLines = allText.split(/\r\n|\n/);lyricPlayer.next();},
"next":function()
{for (i=0;i<lyricPlayer.allTextLines.length;i++){if (lyricPlayer.allTextLines[i].search(/^(\[)(\d*)(:)(.*)(\])(.*)/i)>=0 ){lyricPlayer.line = lyricPlayer.allTextLines[i].match(/^(\[)(\d*)(:)(.*)(\])(.*)/i);lyricPlayer.tim[i] = (parseInt(lyricPlayer.line[2])*60)+ parseInt(lyricPlayer.line[4]);lyricPlayer.lyrics[i]= lyricPlayer.line[6] ;}else{lyricPlayer.countt++;}}lyricPlayer.set_divval();},
"set_scview":function(id){if(lyricPlayer.Mode=="Long"){var classes = document.getElementsByClassName("lyricsItem_class");for(let u=0;u<classes.length;u++){classes[u].style.color=lyricPlayer.Tcolor;}document.getElementById(`lyricsItem_${id}`).style.color=lyricPlayer.Scolor;var element = document.getElementById(`lyricsItem_${id}`);element.scrollIntoView({behavior: 'smooth',block: 'start'});}if(lyricPlayer.Mode=="Line"){var classes = document.getElementsByClassName("lyricsItem_class");
for(let u=0;u<classes.length;u++){
classes[u].style.display="none";
classes[u].style.color=lyricPlayer.Tcolor;}document.getElementById(`lyricsItem_${id}`).style.color=lyricPlayer.Scolor;document.getElementById(`lyricsItem_${id}`).style.display="block";}},
"change_lrc":function(elem){var time = parseInt(elem.currentTime);if(lyricPlayer.main_dict[time]!=undefined){lyricPlayer.set_scview(time)}},
"allTextLines":"",
"lyrics":[],
"tim":[],
"main_dict":{},
"h_lyrics":"",
"countt":0,
"Scolor":"white",
"line":"",
"tmp_count":0,
"Mode":"Long",
"Tcolor":document.getElementById("lyrics_playerMain").style.color,
"setLyrics":function(val){lyricPlayer.h_lyrics=val;lyricPlayer.main_dict={};lyricPlayer.countt=0;lyricPlayer.tim=[];lyricPlayer.lyrics=[];lyricPlayer.allTextLines="";lyricPlayer.processData(lyricPlayer.h_lyrics);lyricPlayer.tmp_count=lyricPlayer.countt;}
}
this works totally fine and perfect

Categories