I want to add coupon code system in e commerce website using laravel 5.8
when i click on apply coupon button it gives me error like "Invalid argument supplied for foreach()" the problem is with that foreach loop in my controller when i remove it then it shows 0 price can anybody help me to solve this problem
here is my controller
public function applycoupon(Request $request){
$coupon = $request->input('coupon_code');
if(Coupons::where('coupon_code',$coupon)->exists())
{
$coupon = Coupons::where('coupon_code',$coupon)->first();
if($coupon->start_date<=Carbon::today()&& Carbon::today()<= $coupon->end_date){
$totalprice = "0";
$cookie_data = stripslashes(Cookie::get('shoping_cart'));
$cart_data = json_decode($cookie_data,true);
foreach ($cart_data as $itemdata){
$product = Product::find($itemdata['item_id']);
$prod_price = $product->offer_price;
// $prod_price_tax = ($prod_price*$product->tax)/100;
$totalprice = $totalprice+($itemdata['item_quantity']*$prod_price);
}
//checking Type (percentage or amount)
if($coupon->coupon_type=='Percentage')
{
$discount_price = ($totalprice/100)*$coupon->coupon_price;
}
elseif($coupon->coupon_price=='amount'||'Amount')
{
$discount_price = $coupon->coupon_price;
}
$grand_total = $totalprice-$discount_price;
return response()->json([
'discount_price' =>$discount_price,
'grand_total' =>$grand_total,
]);
}
else
{
return response()->json([
'status'=> 'coupon code has been expired',
'error_status'=>'error'
]);
}
}
else
{
return response()->json([
'status'=> 'coupon code does not exists',
'error_status'=>'error'
]);
}
}
views.blade file
<div class="card-body">
<div class="d-flex justify-content-between mb-3 pt-1">
<h6 class="font-weight-medium">Subtotal</h6>
<h6 class="font-weight-medium">${{ number_format($total, 2) }}</h6>
</div>
<div class="d-flex justify-content-between">
<h6 class="font-weight-medium">Discount</h6>
<h6 class="font-weight-medium discount_price">0.00</h6>
</div>
</div>
Route
Route::post('apply-coupons','CouponController#applycoupon');
custom js file
custom js file
//Apply coupons
$(document).ready(function () {
$('.apply-coupon-btn').click(function (e) {
e.preventDefault();
var coupon_code = $('.coupon_code').val();
if ($.trim(coupon_code).length == 0) {
error_coupon = "please enter valid coupon";
$('#error_coupon').text(error_coupon);
} else {
error_coupon = "";
$('#error_coupon').text(error_coupon);
}
if (error_coupon != '') {
return false;
}
$.ajax({
method: "POST",
url: "/apply-coupons",
data: {
'coupon_code': coupon_code,
},
success: function (response) {
if (response.error_status == 'error') {
alertify.set('notifier', 'position', 'top-right');
alertify.success(response.status);
$('.coupon_code').val('');
}
else{
var discount_price = response.discount_price;
var grand_total = response.grand_total;
$('.discount_price').text(discount_price);
$('.grand_total').text(grand_total);
}
}
});
});
});
The error Invalid argument supplied for foreach() usually occurs when the argument of foreach() is non-array value.
$cookie_data = stripslashes(Cookie::get('shoping_cart'));
$cart_data = json_decode($cookie_data,true);
foreach ($cart_data as $itemdata){
//
}
The function json_decode() return null if the json cannot be decoded. Therefore, on your code, if $cookie_data has not correct JSON format, the error can be occurred. And the variable $cookie_data is from the value of cookie shopping_cart.
In conclusion, there are two possibilities that could be the cause.
There is no assigned cookie shopping_cart on your browser.
The string value in cookie shopping_cart has incorrect JSON format.
Why don't you check the value of cookie shopping_cart running your code.
Related
I have an issue about showing a ViewBag message with respect to the result of a Contract function.
I wrote some codes to cope with this process but I cannot show the message in the HTML part.
What code should I write in the success part of the AJAX process?
Here is my Html part shown below.
<div class="my-3">
<div class="error-message">#ViewBag.Error</div>
<div class="sent-message">#ViewBag.Success</div>
</div>
Here is my Contract function method shown below.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Contract(string nameSurname = null, string email = null, string subject = null, string message = null)
{
if (nameSurname != null && email != null)
{
SmtpClient smtpClient = new SmtpClient("smtp.gmail.com");
smtpClient.Port = 587;
smtpClient.Credentials = new System.Net.NetworkCredential("gmail address", "gmail address password");
// smtpClient.UseDefaultCredentials = true; // uncomment if you don't want to use the network credentials
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpClient.EnableSsl = true;
MailMessage mail = new MailMessage();
mail.Subject = subject;
mail.IsBodyHtml = true;
mail.Body = message;
//Setting From , To and CC
mail.From = new MailAddress(email);
mail.To.Add(new MailAddress("gmail address"));
smtpClient.Send(mail);
ViewBag.Success = "Success";
}
else
{
ViewBag.Error = "Error";
}
return View();
}
Here is my ajax part shown below.
<script type="text/javascript">
$(document).ready(function () {
$("#submitButton").click(function () {
var nameSurname = $("#nameSurname").val();
var email = $("#email").val();
var subject = $("#subject").val();
var message = $("#message").val();
var form = $('#contactForm');
var token = $('input[name="__RequestVerificationToken"]', form).val();
$.ajax({
url: '/Home/Contract/',
data: {
__RequestVerificationToken: token,
nameSurname: nameSurname, email: email, subject: subject, message: message
},
type: 'POST',
success: function (data) {
// code
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('custom message. Error: ' + errorThrown);
}
});
});
})
</script>
Here is my solution shoen below.
html part.
<div class="my-3">
#if (ViewBag.Success != null)
{
<div class="alert alert-success" role="alert">
#ViewBag.Success
</div>
}
#if (ViewBag.Error != null)
{
<div class="alert alert-danger" role="alert">
#ViewBag.Error
</div>
}
</div>
I want to stop sending information if form validation is false.
I have a button Save with two functions in it:
<span class="logInBTN" v-on:click="validationFields(); function2(model)">Save</span>
The form validation is being proccessed in validationFields():
validationFields() {
if (this.model.codePerson == '') {
document.getElementById('codePerson').style.borderColor = "red";
this.errors.push("Choose a type!\n");
falseValidation = true;
} else {
document.getElementById('codePerson').style.borderColor = "#CCCCCC";
}
if (falseValidation == true) {
alert("Form validation:\n" + this.errors.join(""));
}
}
So if it's not chosen a type from the input field, function2() must not continue.
Update1:
<script>
export default {
components: {
},
data(){
return {
errors: [];
},
},
methods: {
validationFields() {
this.errors = [];
var falseValidation = false;
if (this.model.codePerson == '') {
document.getElementById('codePerson').style.borderColor = "red";
this.errors.push("Choose a type!\n");
falseValidation = true;
} else {
document.getElementById('codePerson').style.borderColor = "#CCCCCC";
}
if (falseValidation == true) {
alert("Form validation:\n" + this.errors.join(""));
}
if(falseValidation == false){
this.createEori(eoriData);
}
}
createEori(eoriData) {
eoriData.state = '1';
eoriData.username = this.$session.get('username');
console.log("updateEori state: " + JSON.stringify(eoriData));
const url = this.$session.get('apiUrl') + 'registerEORI';
this.submit('post',
url,
eoriData
);
},
submit(requestType, url, submitData) {
this.$http[requestType](url, submitData)
.then(response => {
console.log('EORI saved!');
console.log('Response:' + response.data.type);
if("E" == response.data.type){
alert(response.data.errorDescription);
} else {
alert("Saved!");
}
})
.catch(error => {
console.log('EORI rejected!');
console.log('error:' + error);
});
},
},
}
</script>
createEORI is the function2
Update2
Now it works, but the data from the fields it's not send to the server. That's all fields from the page, some are datepickers or an ordinary input text field. Before the change in the browser console show this, if I write a name in the first field it will show up in c1_name etc:
{"state":"1","c1_form":"","c1_identNumber":"","c1_name":"","c1_shortName":"","c1_8_street":"","c1_8_pk":"","c1_8_name":"","c1_8_city":"","c1_8_codeCountry":"","c1_identNumber1":"","c3_name":"","c3_nameShort":"","c3_city":"","c3_codeCountry":"","c3_street":"","c3_pk":"","c3_phone":"","codePerson":"","codeActivity":"","c1_date":"","c5_date":"","c7_date":"","dateFrom":"","dateTo":"","c8_date":"","c1_numberVAT":"","c8_provider":"","c8_number":"","codeMU":"","agreed1":"","agreed2":"","username":"testuser"}
However, after the change the sent data or at least the seen data is only:
{"state":"1","username":"testuser"}
The log is from
console.log("updateEori state: " + JSON.stringify(eoriData));
from createEORI() function
I think it would be better practice to only call one function from the HTML. Something like this:
<span class="logInBTN" v-on:click="submit(model)">Save</span>
submit(model) {
if (this.validateForm(model) == true)
{
// submission process here (maybe call function2())
}
}
validateForm(model) {
if (this.model.codePerson == ''){
document.getElementById('codePerson').style.borderColor = "red";
this.errors.push("Choose a type!\n");
this.handleFalseValidation();
return false;
}
document.getElementById('codePerson').style.borderColor = "#CCCCCC";
return true;
}
handleFalseValidation() {
alert("Form validation:\n" + this.errors.join(""));
}
Ok I fixed the problems with sending the data.
It was my fault.
I will copy the Chris answer. That worked.
When you call this.createEori(eoriData);, eoriData is undefined. It doesn't exist. Use this.createEori(); instead, and in the createEori function, remove the parameter and add var eoriData = {}; as first line. (note this is very basic javascript, how functions and variables work, and completely unrelated to Vue or server requests)
Please help. I've been stuck on the same problem for about two weeks now. So I downloaded the advanced login master script from Github and customized it a bit.
Advanced login script
Everything was going fine until I created a Post class and tried adding an ajax form to the "views/logged_in.php" file. The form validation error messages stopped showing up correctly. I'm trying to check if the input field is empty for the form before submitting the form via Ajax. I'm not used to the way this script has been set up. The index file seems to call the classes. But when I try to add ajax it throws me off completely.
Can somebody please show me the proper way to add a simple ajax form to this script within the "views/Logged in.php" file while displaying an error message if the input field is empty?
P.S. I want to display a PHP error, not a Javascript error. In my Post class I have an array for errors and messages.
Here is my javascript ajax code.
$('form.ajax').on('submit', function() {
var that = $(this),
url = that.attr('action'),
type = that.attr('method'),
data = {};
that.find('[name]').each(function(index, value) {
var that = $(this),
name = that.attr('name'),
value = that.val();
data[name] = value;
});
$.ajax({
url: url,
type: type,
data: data,
success: function(response) {
$("form.ajax")[0].reset();
console.log(response);
}
});
return false;
});
website.com/views/logged_in.php
<form action="<?php echo BASE_URL; ?>contact.php"` method="post" class="ajax">
<div class="new_post_header">
<div class="new_post_avatar"><img src="img/profile_pic_1.png" style="width:40px; height:40px;" /></div>
<textarea name="post_text" id="message" class="new_post_textarea" placeholder="Give a tip"></textarea>
</div><!--.new_post_header-->
<div id="new_post_options">
<div class="icon-camera post_options_icon"></div>
<div class="icon-camcorder post_options_icon"></div>
<div class="icon-tag post_options_icon"></div>
<button name="submit" type="submit" class="post_post_button">Post</button>
<a class="privacy_post_option" id="post_privacy_toggle">
<div class="icon-earth-grid privacy_option_icon"></div>
Public
<div class="icon-more-arrow privacy_option_arrow"></div>
</a>
</div><!--#new_post_options-->
</form><!--.ajax-->
website.com/classes/Post.php class
<?php
class Post
{
/**
* #var object $db_connection The database connection
*/
private $db_connection = null;
/**
* #var string $logged_in_user_id the poster's id variable
*/
public $logged_in_user_id = null;
/**
* #var string $post_text The post text variable
*/
public $post_text = "";
/**
* #var array collection of error messages
*/
public $errors = array();
/**
* #var array collection of success / neutral messages
*/
public $messages = array();
/**
* Checks if database connection is opened and open it if not
*/
private function databaseConnection()
{
// connection already opened
if ($this->db_connection != null) {
return true;
} else {
// create a database connection, using the constants from config/config.php
try {
// Generate a database connection, using the PDO connector
// #see http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
// Also important: We include the charset, as leaving it out seems to be a security issue:
// #see http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers#Connecting_to_MySQL says:
// "Adding the charset to the DSN is very important for security reasons,
// most examples you'll see around leave it out. MAKE SURE TO INCLUDE THE CHARSET!"
$this->db_connection = new PDO('mysql:host='. DB_HOST .';dbname='. DB_NAME . ';charset=utf8', DB_USER, DB_PASS);
return true;
// If an error is catched, database connection failed
} catch (PDOException $e) {
$this->errors[] = MESSAGE_DATABASE_ERROR;
return false;
}
}
}
/**
* creates a new post in the databse
*/
public function submitPost($logged_in_user_id, $post_text)
{
// remove extra space on post text
$post_text = trim($post_text);
// if the post text is empty
if (empty($post_text)) {
// show the errors
$this->errors[] = MESSAGE_USERNAME_EMPTY;
} else if ($this->databaseConnection()) {
// write new post data into database
$query_new_post_insert = $this->db_connection->prepare('INSERT INTO posts (poster_id, post_text, post_date) VALUES(:poster_id, :post_text, NOW())');
$query_new_post_insert->bindValue(':poster_id', $logged_in_user_id, PDO::PARAM_INT);
$query_new_post_insert->bindValue(':post_text', $post_text, PDO::PARAM_STR);
$query_new_post_insert->execute();
// id of new post
$post_id = $this->db_connection->lastInsertId();
// return the id of the last post to be added to database
return $post_id;
}
}
/**
* creates a new post in the databse
*/
public function getPost($logged_in_user_id)
{
// remove extra space on post text
$post_text = trim($post_text);
if ($this->databaseConnection()) {
// write new post into database
$query_new_post_insert = $this->db_connection->prepare('INSERT INTO posts (post_text) VALUES(:post_text)');
$query_new_post_insert->bindValue(':post_text', $post_text, PDO::PARAM_STR);
$query_new_post_insert->execute();
// id of new post
$post_id = $this->db_connection->lastInsertId();
// return the id of the new post
return $post_id;
}
}
}
website.com/contact.php
<?php
// start the seesion so that you can access the $_SESSION variable
session_start();
// put the current logged in user's id in a variable
$logged_in_user_id = $_SESSION['user_id'];
// include the config
require_once('config/config.php');
// include the to-be-used language, english by default. feel free to translate your project and include something else
require_once('translations/en.php');
// load the post class
require_once('classes/Post.php');
// create the post object
$post = new Post(
);
if (isset($_POST['post_text'])) {
// put the post text in a variable
$post_text = $_POST['post_text'];
// put the returned id from the submited post into a variable
$post_id = $post->submitPost($logged_in_user_id, $post_text);
}
?>
Hi i have make your submit button as button and onclick i have called ajax function
function test1()
{
var that = $('.ajax'),
url = 'contact.php',
type = 'POST',
data = {};
that.find('[name]').each(function(index, value) {
var that = $(this),
name = that.attr('name'),
value = that.val();
if(value=='')
{
alert("please enter value of " +name);
}
data[name] = value;
});
$.ajax({
url: url,
type: type,
data: data,
success: function(response) {
if(response==2)
{
alert("plaese enter text");
or
$('.error').html("plaese enter text");
}
if(response==1)
{
$("form.ajax")[0].reset();
}
console.log(response);
}
});
return false;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post" class="ajax">
<div class="new_post_header">
<div class="new_post_avatar"><img src="img/profile_pic_1.png" style="width:40px; height:40px;" /></div>
<textarea name="post_text" id="message" class="new_post_textarea" placeholder="Give a tip"></textarea>
</div><!--.new_post_header-->
<div id="new_post_options">
<div class="icon-camera post_options_icon"></div>
<div class="icon-camcorder post_options_icon"></div>
<div class="icon-tag post_options_icon"></div>
<button type="button" onclick="return test1();" class="post_post_button">Post</button>
<a class="privacy_post_option" id="post_privacy_toggle">
<div class="icon-earth-grid privacy_option_icon"></div>
Public
<div class="icon-more-arrow privacy_option_arrow"></div>
</a>
</div><!--#new_post_options-->
</form><!--.ajax-->
A very simplified way of doing this would be:
$('form.ajax').on('submit', function() {
var empty = true;
$("form.ajax input").each(function(){ // check each input
var val = $(this).val();
if(!$.trim(val) == ""){ // if the inputs are not empty
empty = false; // allow ajax to be submitted
}
});
if(empty){
alert("Input is empty!"); // alert that an input is empty
} else {
// ajax goes here
}
return false; // prevent form post
});
Note: This procedure also works if the inputs contain JUST white space (no text). I would suggest checking for this on the server-side too, not just the client-side (as this is editable within the (potential) attackers) browser.
Good day,
I have a php file (db.php) which contains the following function
function edit_record($id, $value){
if($this->db->query('UPDATE tbl_prototype SET value = ' . $value .' WHERE id_component = '.$id)){
$this->register_changes();
return TRUE;
}
return FALSE;
}
Besides, I have some checkboxes in my html page as follows :
<input id="chk01" type="checkbox" data-onstyle="success" data-toggle="toggle">
<input id="chk02" type="checkbox" data-onstyle="success" data-toggle="toggle">
the html page contains also the following script.
<script>
/* AJAX request to checker */
function check(){
$.ajax({
type: 'POST',
url: 'checker.php',
dataType: 'json',
data: {
counter:$('#message-list').data('counter')
}
}).done(function( response ) {
/* check if with response we got a new update */
if(response.update==true){
var j = response.news;
$('#message-list').html(response.news);
sayHello(j);
}
});
};
//Every 1/2 sec check if there is new update
setInterval(check,500);
</script>
<script>
function sayHello(j){
var json=$.parseJSON(j);
var techname = "";
var techname1 = "";
var c;
var w;
$(json).each(function(i,val){
$.each(val,function(k,v){
if (k=="tech_name")
{
techname = "#" + v;
techname1 = v;
}
else
{
console.log("Mon nom est " + techname + " et ma valeur est " + v);
c=document.getElementById(techname1);
if (c.checked)
{
w = 1;
}
else
{
w = 0;
}
console.log(w);
console.log("techname : " + techname1);
if (v != w)
{
console.log ("Pas identique");
if (v==0)
{
// false
uncheckBox(techname);
}
else
{
// true
checkBox(techname);
}
}
else
{
console.log ("Identique");
}
}
});
});
}
function checkBox(pCtrl)
{
toggleOn(pCtrl);
}
function uncheckBox(pCtrl)
{
toggleOff(pCtrl);
}
</script>
Now for my question: where and how should I specify that I would like to run the function 'edit_record' stored in the 'db.php' file with the two parameters ($id and $value).
Contents of 'checker.php' :
<?php require('common.php');
//get current counter
$data['current'] = (int)$db->check_changes();
//set initial value of update to false
$data['update'] = false;
//check if it's ajax call with POST containing current (for user) counter;
//and check if that counter is diffrent from the one in database
//if(isset($_POST) && !empty($_POST['counter']) && (int)$_POST['counter']!=$data['current']){
if(isset($_POST)){
$data['news'] = $db->get_news2();
$data['update'] = true;
}
//just echo as JSON
echo json_encode($data);
/* End of file checker.php */
Thanks a lot for your valuable inputs. Sorry if the question sounds silly (I'm a newbie in php/ajax/jquery programming).
In modern web apps with rich interface You should go for REST API and create controller which should be in You case in checker.php. Example ( checker.php ):
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
//update code
edit_record($_POST['id'],$_POST['counter]);
}
if ($_SERVER['REQUEST_METHOD'] == 'GET'){
//get code
}
ps. i do not see passing id in ajax, you send only counter, so you should add id like:
...
data: {
id:yourId //here your id
counter:$('#message-list').data('counter')
}
Next thing remove from js:
setInterval(check,500);
and create bind:
$("yourcheckboxselector").on("click",function(e){
check($(this).prop("checked") ) //here you have it was checked or not as boolean
});
We are getting a issue wherein while submitting a form via javascript one of the parameters (invoiceCodes) is not sent to the server. Below is the snippet of the javascript code.
The flow is as follows. When user clicks on "Print" button validateTransition() method is called in which we make a ajax call. After response of that ajax we call couponPopup(url, invoiceCodes). In this function we submit newWinForm but sometimes invoiceCodes parameter is sent empty.
Also checkForInvoiceCode is true in this case which require user to input invoice codes
Is there anything wrong in the manner in which we are putting values in the form which may lead to invoiceCodes being not sent sometimes.
function couponPopup(url, invoiceCodes)
{
var selectedOrders = '';
$(".selectedOrder:checked").each(function() {
selectedOrders += $(this).val() + ',';
});
var frm = document.forms["newWinForm"];
frm.action = url;
frm.selectedShipments.value= selectedOrders;
frm.invoiceCodes.value = invoiceCodes;
console.log("Selected orders are "+selectedOrders);
console.log("Invoice codes with them in order are "+invoiceCodes);
document.getElementById("hiddenInvoiceCodes").value=invoiceCodes;
document.getElementById("hiddenselectedShipments").value=selectedOrders;
frm.submit();
return false;
}
function validateTransition() {
$('#statusChangeSuccess').hide();
$('#statusChangeFail').hide();
var selectedOrders = '';
var invoiceCodes = '';
var flag = 0;
var spaceError = 0;
var commaError = 0;
$(".selectedOrder:checked").each(function() {
selectedOrders += $(this).val() + ',';
<c:if test="${checkForInvoiceCode}">
var emptyPattern = /^\s*$/;
var commaPattern = /,/;
var inv_code = $("#invoice-code-" + $(this).val()).val().trim();
if (emptyPattern.test(inv_code)) {
spaceError = 1;
flag = 1;
}
if (commaPattern.test(inv_code)) {
commaError = 1;
flag = 1;
}
invoiceCodes += inv_code + ",";
</c:if>
});
if(selectedOrders=='') {
alert('Please select at least one order');
return false;
}
if ( flag ) {
if ( commaError ) {
alert('One or more specified codes have comma, please remove comma from them');
}
if ( spaceError ) {
alert('One or more specified codes has been left blank, please fill them up');
}
if ( !commaError && !spaceError ) {
alert('Please contact tech');
}
return false;
}
var inputdata = {"selectedShipments" : selectedOrders,
"statusCode" : "PRINT"
};
//this is where we are making an ajax call
jQuery(function($){
setTimeout(function(){
var ajaxUrl = '/product/update/';
$.ajax({url:ajaxUrl, type: "POST", dataType: 'json', data:inputdata , success: function(data) {
if(data['status'] == 'success') {
//couponPopup function is called where form is submitted
couponPopup("${path.http}/product/print/", invoiceCodes);
$('#statusChangeSuccess').html(data['message']).show();
$(".selectedOrder:checked").each(function() {
$("#row-" + $(this).val()).remove();
});
} else{
$('#statusChangeFail').html(data['message']).show();
}
}});
}, 10 );
});
return false;
}
<form id="newWinForm" name="newWinForm" action="" method="post" target="_blank" >
<input type="hidden" id="hiddenselectedShipments" name="selectedShipments" value="" />
<input type="hidden" id="hiddenInvoiceCodes" name="invoiceCodes" value="" />
</form>
Controller for the form. Invoice codes is sometimes empty even when we are sending it from client side.
#RequestMapping("/product/print")
public void printSelectedPendingOrders(#RequestParam("selectedShipments") String selectedShipments,
#RequestParam(defaultValue = "", value = "invoiceCodes", required = false) String invoiceCodes, ModelMap modelMap, HttpServletResponse httpResponse)
throws IOException, DocumentException, ParserConfigurationException, SAXException {