Codeigniter get random record with limit - sql

I've created a page that load 4 products everytime you scroll down the page with codeigniter and Ajax.
I followed this tutorial for create pagination with codeigniter and jQuery.Everything works fine, moreover I've changed the load type from database using Ajax.
I've got a problem with codeigniter.
When I try to get random record from the table I've got duplicate products.
This is the functions in codeigniter:
UPDATE CONTROLLER
function index()
{
$this->load->helper('url');
$data['description'] = "Description";
$data['keywords'] = "Keywords";
$data['products'] = $this->abitainterni->getAllProductsLimit();
$data['get_products'] = $this->abitainterni->get_products();
$this->load->view('welcome', $data);
}
function get_products($offset)
{
$already_used = $this->input->post('already_used');
$already = explode(',', $already_used);
$data['products'] = $this->abitainterni->getAllProductsLimit($offset, $already);
$arr['view'] = $this->load->view('get_products', $data, true);
$bossy = '';
foreach($data['products'] as $p) {
$bossy .= $p->productID.',';
}
$arr['view'] = $bam;
$arr['ids'] = $bossy;
echo json_encode($arr);
return;
}
UPDATE SCRIPT
<script type="text/javascript">
$(document).ready(function(){
<?
$like_a_boss = "";
foreach($products as $gp):
$like_a_boss .= $gp->productID.',';
endforeach;
?>
var products = '<?= $like_a_boss; ?>';
var loaded_products = 0;
$(".loadMoreProducts").click(function(){
loaded_products += 4;
var dati = "welcome/get_products/" + loaded_products;
$.ajax({
url:'welcome/get_products/' + loaded_products,
type: 'post',
data: {already_used: products},
cache: false,
success: function(data) {
var obj = $.parseJSON(data);
$("#mainContainerProductWelcome").append(obj.view);
already_used += obj.ids;
if(loaded_products >= products - 4) {
$(".loadMoreProducts").hide();
} else {
// load more still visible
}
},
error: function() {
// there's something wrong
}
});
// show spinner on ajax request starts
$(".loading-spinner").ajaxStart(function(){
$(".loading-spinner").show();
$(".text-load").hide();
});
// ajax request complets hide spinner
$(".loading-spinner").ajaxStop(function(){
$(".loading-spinner").delay(5000).hide();
$(".text-load").show();
});
return false;
});
// submit form contact
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() >= $(document).height()) {
// click on load more btn
$(".loadMoreProducts").click();
return false;
}
});
});
</script>

you'll need to keep track of the products you've already queried, throw their id's in an array, and then use something like a where not in. So something like this:
function getAllProductsLimit($offset=0, $already_used = array(0))
{
$this->db->order_by('productID', 'RANDOM');
$this->db->where_not_in('productID', $already_used);
$query = $this->db->get('product', 4, $offset);
if($query->num_rows() > 0){
return $query->result();
} else {
return 0;
}
}
NEW CONTROLLER
function index()
{
$this->load->helper('url');
$data['title'] = "Scopri i nostri prodotti";
$data['description'] = "Description";
$data['keywords'] = "Keywords";
$data['products'] = $this->abitainterni->getAllProductsLimit();
$data['get_products'] = $this->abitainterni->get_products();
$this->load->view('welcome', $data);
}
function get_products($offset)
{
$already_used = $this->input->post('already_used');
$already = explode(',', $already_used);
$data['products'] = $this->abitainterni->getAllProductsLimit($offset, $already);
$arr['view'] = $this->load->view('get_products', $data, true);
$bossy = '';
foreach($data['products'] as $p)
{
$bossy .= $->productID.',';
}
$arr['view'] = $bam;
$arr['ids'] = $bossy;
echo json_encode($arr);
return;
}
NEW SCRIPT
<script type="text/javascript">
$(document).ready(function(){
<?
$like_a_boss = '';
foreach($get_products as $gp):?>
$like_a_boss .= $gp->productID.',';
endforeach;?>
var products = '<?= $like_a_boss; ?>';
var loaded_products = 0;
$(".loadMoreProducts").click(function(){
loaded_products += 4;
var dati = "welcome/get_products/" + loaded_products;
$.ajax({
url:'welcome/get_products/' + loaded_products,
type: 'post',
data: {already_used: products},
cache: false,
success: function(data) {
var obj = $.parseJSON(data);
$("#mainContainerProductWelcome").append(obj.view);
already_used += obj.ids;
if(loaded_products >= products - 4) {
$(".loadMoreProducts").hide();
} else {
// load more still visible
}
},
error: function() {
// there's something wrong
}
});
// show spinner on ajax request starts
$(".loading-spinner").ajaxStart(function(){
$(".loading-spinner").show();
$(".text-load").hide();
});
// ajax request complets hide spinner
$(".loading-spinner").ajaxStop(function(){
$(".loading-spinner").delay(5000).hide();
$(".text-load").show();
});
return false;
});
// submit form contact
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() >= $(document).height()) {
// click on load more btn
$(".loadMoreProducts").click();
return false;
}
});
});
</script>
Then whereever your using that function, before you echo out your results to your ajax function, run a quick foreach to add the ids of the products you just got to the already used array. You can either store this is session, or pass it back and forth between your ajax stuff, or if your ajax stuff is written fine, you don't need to worry about it, just attach the product id's to each product you're displaying using a data attribute or something and generate the array that way.

Related

Store Auth::user()-id in DB using SQL query in laravel

I want to store Auth::user()->id on the default column user_id in the SQL query shown below.
I tried to set put like this but does not send any data to the database.
public function saveLoadingsData() {
//Validate for a valid Post Request
if (isset($_POST['orderNumber']) && isset($_POST['Truck']) && isset($_POST['receiptNumber']) && isset($_POST['items'])) {
// {"orderNumber":"CRS1104200001","agentId":"3","items":[{"itemId":"4","itemName":"Embe","quantity":"13"}]}
$orderNumber = $_POST['orderNumber'];
$items = $_POST['items'];
$receiptNumber = $_POST['receiptNumber'];
$Truck = $_POST['Truck'];
$driverName = $_POST['driverName'];
foreach ($items as $singleItem) {
$data = array('order_no' => $orderNumber,'user_id'=>Auth::user()->id,"receiptNumber" => $receiptNumber, "Truck" => $Truck, "driverName" => $driverName, "pid" => $singleItem['itemId'], "qty" => $singleItem['quantity']);
// print_r($data);
DB::table('loadings')->insert($data);
// return redirect()->back();
}
// return redirect()->back();
echo "Success";
}
My ajax function
$("#btnSaveOrder").on('click', function(e){
var orderNumber=$("#order_no").val();
var receiptNumber=$("#receiptNumber").val();
var Truck=$("#Truck").val();
var driverName=$("#driverName").val();
var jsonData=convertTableToJson();
$.ajax('/api/loading/saveLoadingsData', {
type: 'POST',
data: {
orderNumber:orderNumber,
receiptNumber:receiptNumber,
Truck:Truck,
driverName:driverName,
items:jsonData
},
success: function (data, status, xhr) {
alert("Data Saved");
document.location.reload(true);
},
error: function (jqXhr, textStatus, errorMessage) {
console.log(errorMessage);
}
});
});
var convertTableToJson = function(){
var rows = [];
$('table#tableSelectedItems tr').each(function(i, n){
if (i!=0) {
var $row = $(n);
rows.push({
itemId: $row.find('td:eq(0)').text(),
itemName: $row.find('td:eq(1)').text(),
quantity: $row.find('td:eq(2)').text(),
});
}
});
return rows;
};
My api route
Route::post('loading/saveLoadingsData', 'LoadingController#saveLoadingsData');
Can someone help me?
I recommend you the following
Pass the $request object in your method and log all object, maybe are missing data and for that reason it does not meet the condition:
saveLoadingsData(Request $request){
Log::info(json_encode($request->all()));`
}
Then check your logs files to see the result in /storage/logs/laravel.log

QZ TRAY PRINITING ORDER NOT IN SEQ

I'm trying to print qz tray from javascript.
I have barcode with number in ascending order 1,2,3,4, 5 and so on.
I looping the seq correctly . but when printed out, it was not in order.
setTimeout("directPrint2()",1000);
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
function directPrint2(){
var data;
var xhttp;
var v_carton = "' || x_str_carton ||'";
var carton_arr = v_carton.split('','');
var v1 = "' ||
replace(x_zebra_printer_id, '\', '|') ||
'".replace(/\|/g,"\\");
if(v1 == ""){
alert("Please setup ZPL Printer");
}
else{
xhttp=new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
data = [ toNative(this.responseText) ];
printZPL(data, v1);
}
};
for (var j = 0; j < carton_arr.length; j++){
var url = "' || x_wms_url ||
'WWW_URL.direct_print_label?in_carton_no="+toValidStr(carton_arr[j]);
xhttp.open("GET", url, false);
xhttp.send();
sleep(5000);
}
}
};
',
'javascript'
What's missing from your example:
I do not see any looping logic in the example calling the printZPL function,
printZPL isn't a QZ Tray function and you're missing the code snippet which it calls. Usually this would be qz.print(config, data);.
Regardless of the missing information, the qz.print(...) API is ES6/Promise/A+ based meaning if you want to call qz.print multiple times in a row you need to use a Promise-compatible technique. (e.g. .then(...) syntax) between your print calls as explained in the Chaining Requests guide.
To avoid this, you can concatenate all ZPL data into one large data array. Be careful not to spool too much data at once.
If you know exactly how many jobs you'll be appending, you can hard-code the promise chain:
qz.websocket.connect()
.then(function() {
return qz.printers.find("zebra"); // Pass the printer name into the next Promise
})
.then(function(printer) {
var config = qz.configs.create(printer); // Create a default config for the found printer
var data = ['^XA^FO50,50^ADN,36,20^FDRAW ZPL EXAMPLE^FS^XZ']; // Raw ZPL
return qz.print(config, data);
})
.catch(function(e) { console.error(e); });
Finally, if you do NOT know in advanced how many calls to qz.print(...) you can use a Promise loop as explained in the Promise Loop guide.
function promiseLoop() {
var data = [
"^XA\n^FO50,50^ADN,36,20^FDPRINT 1 ^FS\n^XZ\n",
"^XA\n^FO50,50^ADN,36,20^FDPRINT 2 ^FS\n^XZ\n",
"^XA\n^FO50,50^ADN,36,20^FDPRINT 3 ^FS\n^XZ\n",
"^XA\n^FO50,50^ADN,36,20^FDPRINT 4 ^FS\n^XZ\n"
];
var configs = [
{ "printer": "ZDesigner LP2844-Z" },
{ "printer": "ZDesigner LP2844-Z" },
{ "printer": "ZDesigner LP2844-Z" },
{ "printer": "ZDesigner LP2844-Z" }
];
var chain = [];
for(var i = 0; i < data.length; i++) {
(function(i_) {
//setup this chain link
var link = function() {
return qz.printers.find(configs[i_].printer).then(function(found) {
return qz.print(qz.configs.create(found), [data[i_]]);
});
};
chain.push(link);
})(i);
//closure ensures this promise's concept of `i` doesn't change
}
//can be .connect or `Promise.resolve()`, etc
var firstLink = new RSVP.Promise(function(r, e) { r(); });
var lastLink = null;
chain.reduce(function(sequence, link) {
lastLink = sequence.then(link);
return lastLink;
}, firstLink);
//this will be the very last link in the chain
lastLink.catch(function(err) {
console.error(err);
});
}
Note: The Promise Loop is no longer needed in QZ Tray 2.1. Instead, since 2.1, an array of config objects and data arrays can be provided instead.

YouTube OnStateChange with multiple players on the same page

I have multiple YouTube players on a single page inside a banner slider and I want to use the YouTube Player API to control them and do other stuff based on the state of the video's. I have the code below which I'm pretty sure of used to work fine where any state changes where registered. But it doesnt work for me anymore. The YouTube object is still there and I can use it to start and stop a video but the onStateChange event never gets triggered. What is wrong with this code?
var YT_ready = (function() {
var onReady_funcs = [],
api_isReady = false;
return function(func, b_before) {
if (func === true) {
api_isReady = true;
for (var i = 0; i < onReady_funcs.length; i++) {
onReady_funcs.shift()();
}
}
else if (typeof func == "function") {
if (api_isReady) func();
else onReady_funcs[b_before ? "unshift" : "push"](func);
}
}
})();
function onYouTubePlayerAPIReady() {
YT_ready(true);
}
var players_homepage = {};
YT_ready(function() {
$("li.video iframe.youtube").each(function(event) {
var frameID_homepage = $(this).attr('id');
if (frameID_homepage) {
players_homepage[frameID_homepage] = new YT.Player(frameID_homepage, {
events: {
'onStateChange': onPlayerStateChange_homepage
}
});
}
});
});
(function(){
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
})();
function onPlayerStateChange_homepage(event) {
if (event.data === 0) {
// do something on end
} else if (event.data === 1) {
// do something on play
} else if (event.data === 2) {
// do something on pause
}
}
function pauseVideo_homepage(previousVideo) {
players_homepage[previousVideo].pauseVideo();
}
function playVideo_homepage(currentVideo) {
players_homepage[currentVideo].playVideo();
}

Calling HttpGet Method Using Ajax on IpagedListPager Mvc

I want to call HttpGet method on every page using ajax using IpagedList in MVC
Controller [HttpGet]
public ActionResult TestStarted(int TestId,DateTime End_Time,int page=1)
{
ViewBag.ct = 0;
ViewBag.TestId = TestId;
var Questions = GetNoOfQuestions().ToList();
ViewBag.Questions = Questions;
EAssessmentNew.BAL.StudentBal studBal = new EAssessmentNew.BAL.StudentBal();
EAssessmentNew.Dal.Student_Answer_Master _studAnsdal = new EAssessmentNew.Dal.Student_Answer_Master();
String TestName = studBal.FetchTestName(TestId);
ViewBag.TestName = TestName;
ViewBag.EndTime = End_Time;
List<Question> model = new List<Question>();
model = new Test_Planning().Fetch_Question_By_Test(TestId);
ViewBag.total = model.Count();
if (Request.QueryString["cnt"] != null)
{
int count = Convert.ToInt16(Request.QueryString["cnt"].ToString());
List<int> ChkOptions = studBal.GetCheckedAnswers((int)TestId, model[count].QuestionId, (int)(studBal.getStudentId(Session["sname"].ToString())));
ViewBag.ChkOptions = ChkOptions;
int cnt = 0;
if (ChkOptions.Count() != 0)
{
for (int i = 0; i < model[count].Options.Count(); i++)
{
if (model[count].Options[i].OptionId == ChkOptions.ElementAt(cnt))
{
model[count].Options[i].IsChecked = true;
cnt++;
}
else
{
model[count].Options[i].IsChecked = false;
}
if (cnt >= ChkOptions.Count() - 1)
{
cnt = ChkOptions.Count() - 1;
}
}
}
return View(model.OrderByDescending(v => v.Question_Id).ToPagedList(page, 1));
}
else
{
return View(model.OrderByDescending(v => v.Question_Id).ToPagedList(page, 1));
}
}
My View
<script type="text/javascript">
var TestId ='#ViewBag.TestId'
function loadQuestions() {
alert("ok")
$.ajax({
url: '#Url.Action("Student","TestStarted")',
data: { TestId:TestId },
contentType:"application/json",
success:function(responce){
}
});
}
</script>
<div class="pagedList">
#Html.PagedListPager(Model, page => Url.Action( "",new { onclick="loadQuestions()"}), PagedListRenderOptions.TwitterBootstrapPager)
</div>
I have done paging using IpagedList i want to call HttpGet Method Of controller on each and every page but i want this to perform without page refresh i have written ajax for it now i just want to know how can i call that ajax method using #Html.PagedListPager and on onClick event
Just Correct your url in ajax request as :
Instead of this
url: '#Url.Action("Student","TestStarted")'
It should be this
url: '#Url.Action("TestStarted","Student")'
and #Html.PagedListPager produces 'anchor' tag in html so you can put a click event on document as shown :-
$(document).on('click', 'a', function() {
$.ajax({
url: this.href,
type: 'GET',
datatype: "html",
data :{ TestId : $("#TestId").val(), End_Time :$("#End_Time").val(), page :$("#page").val() }
cache: false,
success: function(result) {
$('#results').html('');
$('#results').html(result);
}
});
return false;
});
In above code click event binds with every 'anchor' tag so if you need for specific 'anchor' tags then you can specify class as $(.pager).on('click', 'a', function() {}) and here '#results' is the target div id whose html is coming from controller action in your case this id may be different.

Saving data from XMLHttpRequest Response to my IndexedDB

I have created a json file containing my Sql Server datas. With the XmlHttpRequest's GET method, I am reading json file and iterating and saving those records to my IndexedDB.. Everything is working fine.. After the end of the iteration, I wrote a code to alert the user.. But the alert message is displayed very quickly, but when I see it in the console window, the saving operation is till processing.. I want to alert the user, only after the operation is completed..
My code is,
if (window.XMLHttpRequest) {
var sFileText;
var sPath = "IDBFiles/Reservation.json";
//console.log(sPath);
var xhr = new XMLHttpRequest();
xhr.open("GET", sPath, 1);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
if (xhr.responseText != "") {
sFileText = xhr.responseText;
//console.log(sFileText);
var val = JSON.parse(sFileText);
var i = 0;
var value = val.length;
for(var i in val)
{
var code = val[i].RTM_res_category_code;
var desc = val[i].RTM_res_category_edesc;
addReserv(code, desc);
}
if(i >= value-1) {
console.log("Reservation Load Completed... "+i);
document.getElementById("status").innerHTML = "Reservation Loading Success...";
}
}
}
}
xhr.send();
}
//Passing Parameters to Reservation
function addReserv(code, desc)
{
document.querySelector("#status").innerHTML = "Loading Reservation.. Please wait...";
var trans = db.transaction(["Reservation"], "readwrite");
var store = trans.objectStore("Reservation");
//console.log(store);
var reserv={ RTM_res_category_code : code, RTM_res_category_edesc : ''+desc+'' };
var request = store.add(reserv);
request.onerror = function(e) {
console.log(e.target.error.name);
document.querySelector("#status").innerHTML = e.target.error.name;
}
request.onsuccess = function(e) {
console.log("Reservation Saved Successfully.");
//document.querySelector("#status").innerHTML = "Reservation Loaded Successfully.";
}
}
Thanks for the question.
What you are currently doing works, but the alert comes to soon because of the async nature of the IDB.
What you should to avoid this.
1. Create your transaction only once.
2. Do all your operations in this one transaction.
3. The transaction object has an oncomplete callback you can use to notify the user.
Concrete on your example. Instead of looping over the items in the ajax callback, pass the collection to your add method and loop there
if (window.XMLHttpRequest) {
var sFileText;
var sPath = "IDBFiles/Reservation.json";
//console.log(sPath);
var xhr = new XMLHttpRequest();
xhr.open("GET", sPath, 1);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
if (xhr.responseText != "") {
sFileText = xhr.responseText;
//console.log(sFileText);
var val = JSON.parse(sFileText);
import(val);
}
}
}
xhr.send();
}
function import(values)
{
document.querySelector("#status").innerHTML = "Loading Reservation.. Please wait...";
var trans = db.transaction(["Reservation"], "readwrite");
var store = trans.objectStore("Reservation");
var i = 0;
var value = val.length;
for(var i in val)
{
var code = val[i].RTM_res_category_code;
var desc = val[i].RTM_res_category_edesc;
var reserv={ RTM_res_category_code : code, RTM_res_category_edesc : ''+desc+'' };
var request = store.add(reserv);
request.onerror = function(e) {
console.log(e.target.error.name);
document.querySelector("#status").innerHTML = e.target.error.name;
}
request.onsuccess = function(e) {
console.log("Reservation Saved Successfully.");
//document.querySelector("#status").innerHTML = "Reservation Loaded Successfully.";
}
}
trans.oncomplete = function () {
console.log("Reservation Load Completed... "+i);
document.getElementById("status").innerHTML = "Reservation Loading Success...";
}
}