I'm working on a shopping cart function using session. I am trying to make function that update the quantity of an item in shopping cart and reload the subtotal and the cart's items list on header of the page.The function update the session and reload the subtotal but the problem is that it reload the cart's items list with the old session's information (before i updated). I want it to get the new session's information. Could you give me any ideas how to fix this? Many thanks!
I tried js setTimeout($('#cart-button').load(),2000) to delay the function to see if it can get the new session but it's still not working.
P/s: I 've just tried to put $this->ajaxReloadCart($cart->totalQty, $this->money($cart->totalPrice), $cart->items); in subOneItem() function, it works fine but the cart list is now at the subtotal div
Here is my js function:
$('#sub-1-{{$item['item']['id']}}').click(function(){
var qty = $('#qty-{{$item['item']['id']}}').val();
var int_qty = parseInt(qty);
if(int_qty > 1){
int_qty--;
$('input#qty-{{$item['item']['id']}}').val(int_qty);
$('#sub-total').load('sub-one/{{$item['item']['id']}}');
$('#cart-button').load('reload-mini');
}
if(int_qty <= 1){
int_qty = 1;
}
});
My routes
Route::get('sub-one/{id}','PageController#subOneItem');
Route::get('reload-mini','PageController#reloadMiniCart');
and my controller functions:
-ajaxReloadCart:
public function ajaxReloadCart($totalQty, $totalPrice, $items){
echo ' <button type="button" class="btn btn-default">
<a href="view-cart">
<i class="fa fa-shopping-cart fa-lg"></i>
<div class="item-number">'
.$totalQty.
'</div>
</a>
</button>';
echo '<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>';
echo ' <ul class="dropdown-menu cart-items-list" id="cart-items-list">';
foreach($items as $item){
$price = $this->money($item['item']['price']);
echo ' <li>
<div class="row" style="margin-left:0; margin-top:10px;">
<div class="col-xs-4 col-sm-4 col-md-4 col-lg-4">
<img src="upload/product/'.$item['item']->productimg->first()->name.'" width="100" />
</div>
<div class="col-xs-8 col-sm-8 col-md-8 col-lg-8">
<div class="row">
<strong>'.$item['item']['name'].'</strong>
</div>
<div class="row">'
.$price.' X '.$item['qty'].
'</div>
</div>
</div>
</li>';
}
echo ' <li><a><strong>Subtotal:</strong> <div class="pull-right">'.$totalPrice.'</div></a></li>
<li role="separator" class="divider"></li><li>To Checkout</li></ul>';
}
-subOneItem:
public function subOneItem($id){
$product = Product::find($id);
$oldCart = Session::has('cart') ? Session::get('cart') : null;
$cart = new Cart($oldCart);
$cart->subOne($product, $id);
Session::put('cart',$cart);
$totalPrice = $this->money($cart->totalPrice);
// display mini cart and total price
echo $totalPrice;
}
-reloadMiniCart:
public function reloadMiniCart(){
$oldCart = Session::has('cart') ? Session::get('cart') : null;
$cart = new Cart($oldCart);
$this->ajaxReloadCart($cart->totalQty, $this->money($cart->totalPrice), $cart->items);
}
Try to clear the session first before you assign the new cart values to the session
with Session::forget('cart'); or clear all session with Session::flush()
then assign the new cart info to session
in your subonitem() function after
Session::put('cart',$cart);
add Session::save();
I found other way to get the cart list reloaded but i think it's not the best way.
if you guys find any other ways, please comment below. I want to find a better way.
my solution:
reload cart list every 1s
setInterval(function(){
$('#cart-button').load('reload-mini');
},1000);
Related
On my site I'm building my own kind of blog for the users and would like for the comments that people place under the posts to be editable. Unfortunately I haven't been able to get this far with it. Because they all have the same class/id.
I've tried using data-id, but I'm not really adept when it comes to those. Other than that I've searched for ages, but couldn't really find anything that could help me with the code I have.
Function that gets the post and comments:
public function announcement(Announcement $announcement)
{
$announcements = Announcement::findOrFail($announcement->id);
$category_lists = Category::withCount('posts')->get();
$replies = Reply::where('post_id', $announcement->id)->paginate(5);
return view('announcements.details', compact('announcements', 'category_lists', 'replies'));
}
The comment foreach:
#foreach($replies as $reply)
<div class="announcement">
#if(Auth::user()->admin == 1 || Auth::user()->id == $reply->user_id)
<i class="fal fa-dumpster"></i>
#endif
#if(Auth::user()->id == $reply->user_id)
<i class="fal fa-pencil float-right" id="yeet" class="float-right showhidereply" style="color: #007ac3; margin-right: 10px;" data-id="{{ $reply->id }}"></i>
#endif
<p style="font-size: 0.8rem;">{{$reply->created_at->diffForHumans()}} | Geplaatst door <span>{{$reply->username}}</span></p>
<p style="margin-top: -10px;">{!! $reply->post_content !!}</p>
#if(Auth::user()->id == $reply->user_id)
<div class="reply-expand-{{$reply->id}}" style="display: none;">
<form method="POST" action="{{ route('Reply Edit', ['id' => $reply->id]) }}">
#csrf
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Reactie Aanpassen:</strong>
<textarea class="form-control summernote" name="detail">{!! $reply->post_content !!}</textarea>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<button type="submit" class="btn btn-primary pull-right" style="border-radius: 0px; box-shadow: 0px 1px 10px -4px #000000;">Aanpassen</button>
</div>
</form>
</div>
#endif
<hr>
</div>
#endforeach
Editting function:
public function postSummernoteeditorReply(Request $request, $id){
$this->validate($request, [
'detail' => 'required',
]);
$detail=$request->detail;
$dom = new \DomDocument();
$dom->loadHtml( mb_convert_encoding($detail, 'HTML-ENTITIES', "UTF-8"), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$images = $dom->getElementsByTagName('img');
foreach($images as $img){
$src = $img->getAttribute('src');
// if the img source is 'data-url'
if(preg_match('/data:image/', $src)){
// get the mimetype
preg_match('/data:image\/(?<mime>.*?)\;/', $src, $groups);
$mimetype = $groups['mime'];
// Generating a random filename
$filename = uniqid();
$filepath = "/img/blog/$filename.$mimetype";
// #see http://image.intervention.io/api/
$image = Image::make($src)
// resize if required
/* ->resize(300, 200) */
->encode($mimetype, 100) // encode file to the specified mimetype
->save(public_path($filepath));
$new_src = asset($filepath);
$img->removeAttribute('src');
$img->setAttribute('src', $new_src);
} // <!--endif
} // <!--endforeach
$detail = $dom->saveHTML();
$summernote = Summernote::find($id);
$summernote->post_content = $detail;
//dd($summernote->post_content);
//dd($summernote->post_id);
$summernote->update();
return redirect(url()->previous());
}
JQuery to show the editting form:
$(document).ready(function() {
$('.summernote').summernote({
height: 400,
});
$('#yeet').click(function() {
$('.reply-expand').toggle("slide");
});
// change the selector to use a class
$("#yeet").click(function(){
// this will query for the clicked toggle
var $toggle = $(this);
// build the target form id
var id = "#replycomment-" + $toggle.data('id');
$( id ).toggle('slide');
});
});
The expected outcome should be to be able to edit each comment individually by clicking on the edit icon(pencil) next to the comment and having the form show before being able to edit. I already have the edit function and displaying the form working, but only for the first comment.
I hope someone will be able to help! Many thanks!
EDIT: When I click the edit button on the first comment, it opens the form with the data of the second/last comment, but clicking the second/last edit button doesn't do anything.
First have a unique Id for the clickable items. Right now they all have the same id (yeet) and that could be the cause of the problem.
<i class="fal fa-pencil float-right yeet" id="yeet-{{ $reply->id }}" class="float-right showhidereply" style="color: #007ac3; margin-right: 10px;"></i>
We can keep yeet as a class to handle the click events for all the comments. This way each comment will have a different Id and they will all go through the same click event.
Now change the selectors to use the yeet class intead of the id.
$('.yeet').click(function() {
//get the clicked element id and toggle the respective form
}
You have to add unique ids to the form in the same way as before to be able to toggle each one independently.
I'm working on a system where the user can select a product and go to the next page. This product then gets saved in the session using laravel sessions. When the user decides to go to the next page and come back. The chosen product is indeed saved in the session, but the is no way for them to see what product they have chosen because the class isn't applied to the product that was chosen.
The code may clarify it better:
#foreach($themes as $theme)
<div class="col-md-4 mb-4">
<div class="card theme-card card-hover depth-2 border-0" id="theme-id-{{$theme->id}}">
<a href="" class="theme-link" data-toggle="modal" data-target="#theme{{ $theme->id }}">
<div class="card-image" style="height: 200px; background-image: url('/uploads/{{ $theme->thumbnail }}'); background-size: cover; background-position: center center;"></div>
<div class="card-body">
<div class="row">
<div class="col-md-2 vertical-center">
<i class="fab fa-magento fa-lg"></i>
</div>
<div class="col-md-10">
<p class="m-0">{!! str_limit($theme->name, $limit = 32, $end = '...') !!}</p>
<small class="text-muted">{{ $theme->productable_type }}</small>
</div>
</div>
</div>
</a>
<div class="card-footer bg-white border-0 text-right pt-0">
<div class="row">
<div class="col-md-6 text-left">
<input type="hidden" class="theme-name" name="theme[{{$theme->id}}]">
{{--<input type="hidden" value="{{ $theme->composer_package }}">--}}
<button data-card-id="{{$theme->id}}" class="btn btn-orange btn-sm btn-theme-choice">Kiezen</button>
</div>
<div class="col-md-6 text-right">
<span style="font-size: 20px;" >€ {{ $theme->price }} EUR</span>
</div>
</div>
</div>
</div>
</div>
#endforeach
In the above code, I for each trough every so-called "Theme" and I'm giving the ID of the theme as a data target and as ID. Then in my Javascript code, I do the following:
$('.btn-theme-choice').on('click', function (event) {
event.preventDefault();
newSelectedCardId = $(event.target).data('card-id');
if(cardId === null) {
cardId = newSelectedCardId;
} else if (cardId !== newSelectedCardId) {
$('#theme-id-' + cardId).removeClass('theme-chosen').find("input[name='theme["+cardId+"]']").val('');
cardId = null;
}
var card = $('#theme-id-' + cardId );
card.toggleClass('theme-chosen');
selectedCardInput = card.find("input[name='theme["+cardId+"]']");
if( !$('.theme-card').hasClass('theme-chosen') ) {
selectedCardInput.val('');
} else if ( $('.theme-card').hasClass('theme-chosen') ) {
selectedCardInput.val('selected');
}
console.log(selectedCardInput);
});
Here I add the class to the card so the user can See which card they've selected. This choice then gets saved in the session using some PHP code in the controller
if( $theme == null ) {
return redirect('plugins');
} elseif( $theme != null ) {
foreach($this->predefinedArray as $value) {
$request->session()->put('chosen_theme.' . $value, $theme->$value);
}
$request->session()->put('chosen_theme.composer_package', $theme->productable->composer_package);
return redirect('plugins');
}
problem
How can I read the session and add the class to the card with the IDs that were stored in the session so if the person leaves the page and comes back, they can see what cards they've selected?
Thanks in advance
Try this in your view..
<div class="card theme-card card-hover depth-2 border-0 {{ \Session::get('chosen_theme.composer_package') == $theme->id ? 'theme-chosen' : '' }}" id="theme-id-{{$theme->id}}">
Whenever the theme id is in the session and the page loaded the class will be added, and if it is not in the session then the class won't be added.
Let me know the result..
I can not run my like counter in javascript.
The replacement of the empty heart with the full one works properly but the counter update no. Can someone help me? Thank you
$query2 = mysql_query("SELECT * FROM totlike WHERE id_user_like = $id_user AND id_post_like = ". $risultato['id']."");
if(mysql_num_rows($query2) ==1) {
$like='<i class="glyphicon glyphicon-heart" id="'. $risultato['id'] .'"></i>';
} else {
$like='<i class="glyphicon glyphicon-heart-empty" id="'. $risultato['id'] .'"></i>';
}
echo '<div class="list" id="list_'. $risultato['id'] .'">
<div class="panel panel-default">
<div class="btn-group pull-right postbtn">
<button type="button" class="dotbtn dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="dots"></span> </button>
<ul class="dropdown-menu pull-right" role="menu">
<li>Segnala</li>
'. $delete .'
</ul>
</div>
<div class="col-md-12">
<div class="question" id="question8025"><div class="img imgLiquid imgLiquid_bgSize imgLiquid_ready" style="width: 60px; height: 60px; margin: 0px auto; background-image: url("download.jpg"); background-size: cover; background-position: center center; background-repeat: no-repeat;"><img src="download.jpg" id="questionavatar" style="display: none;"></div>
<div class="media-body">
<h4 class="media-heading">'. $risultato['username'] .'<br>
<small><i class="fa fa-clock-o"></i> Yesterday, 2:00 am</small> </h4>
<p><h4>'. $status = nl2br($risultato['post']) .'</h4></p>
<ul class="nav nav-pills pull-left ">
<li>'.$like.' '.$risultato['total_like'].'</li>
</ul>
</div>
</div>
</div>
</div>
</div>';
and then
function like(id_post, tot_like) {
$.ajax({
type: "POST",
url: '../ajax/like.php',
data:{id_post:id_post},
complete: function() {
var elem = $('#'+id_post).attr('class');
if (elem=="glyphicon glyphicon-heart") {
$('#'+id_post).removeClass('glyphicon glyphicon-heart').addClass('glyphicon glyphicon-heart-empty');
$('#'+id_post).text(tot_like - 1);
} else {
$('#'+id_post).removeClass('glyphicon glyphicon-heart-empty').addClass('glyphicon glyphicon-heart');
$('#'+id_post).text(tot_like + 1);
}
}
});
When I click the counter goes to -1 or +2
You must have a refresh after you update by clicking on +1 or -1 which you are not doing it.
Also you must do ++ or -- which will be better.
1º Get the total likes, 2º show them as you are doing till now, 3º update which the user action, 4º get again refreshing o just update DOM object with +1 or -1 but will be quite useless and there may occur some error soon or mistake.
How do you delete a div that is generated by a for loop? I have this code that generates divs:
EDIT: I have tried the changes of #Andrew Liberio but what happened is that my applicant divs have scattered all over the place. This is the new code and the script as well. Notice how I had put the ending semicolon of the for loop in order to get put the the index in the ajax. (Not seen in the code block for some reason but it goes like this >/script> <%}%>
<% ApplicantDAO applicantDAO = new ApplicantDAO();%>
<% for (int i = 0; i < applicantDAO.viewApplicant().size(); i++) {%>
<div class="column">
<div class="col-sm-3 col-xs-4">
<div class="list-group">
<a class="list-group-item active">
<img src = "th_1x1.jpg" class = "img-responsive" alt = "Responsive Image" width = "100%" height ="100">
<h4 class="list-group-item-heading" id="guardName<%=+i%>" id="guardName<%=+i%>"><%=applicantDAO.viewApplicant().get(i).getApplicantFirstName() + " "%>
<%=applicantDAO.viewApplicant().get(i).getApplicantLastName()%></h4>
</a>
<a class="list-group-item">
<p class="list-group-item-text" id="applyingFor<%=+i%>" id="applyingFor<%=+i%>"><%=applicantDAO.viewApplicant().get(i).getApplyingFor()%></p>
</a>
<a class="list-group-item" data-toggle="modal" href="#moreDetails<%=+i%>">
<button class="btn btn-primary btn-lg btn-block" id="moreDetails">More Details</button>
</a>
<a class="list-group-item">
<button type="button" class="btn btn-default" aria-label="Left Align">
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
</button>
<button type="button" class="btn btn-default" aria-label="Left Align">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
</a>
<script>
$(".delete").on("click", function () {
var id = $(this).attr("delete<%=applicantDAO.viewApplicant().get(i).getApplicantID()%>"); //get the id of the row
$.post("url_to_servlet_responsible_to_exclude_item", {
tId: id,
someOtherData: "anyData"
}).done(function () {
//if everything went ok,
//delete the div
$("div#" + id).remove();
});
})
</script>
But I dont know how to delete it at the same time delete it at the database. I use a jsp and servlet. This is my code for delete:
public boolean rejectApplicant(Applicant RejectedApplicant) {
try {
DBConnectionFactory myFactory = DBConnectionFactory.getInstance();
Connection conn = myFactory.getConnection();
String query = "delete from applicant where applicantID = ?";
PreparedStatement pstmt = conn.prepareStatement(query);
int rows = pstmt.executeUpdate();
conn.close();
pstmt.close();
return true;
} catch (SQLException ex) {
Logger.getLogger(ApplicantDAO.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
I think that the same logic applies when transferring the values of the div to the database. The page is an applicant page where applicants are screened then if they do not pass, they will be removed and when they are accepted, the values will be passed to the database. Please suggest on what should I do. I already searched javascript and jquery but I just dont understand the terms like nodes etc. Any help or leads would be appreciated. Thank you!
You could pass an id to each div or/and to each button as #LAROmega suggested.
<div class="column" id="<%=applicantDAO.viewApplicant().get(i).getApplicantId()">
<div class="col-sm-3 col-xs-4">
...
<button type="button" class="btn btn-default delete" aria-label="Left Align" id="<%=applicantDAO.viewApplicant().get(i).getApplicantId()">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
Then, you could use this script to delete the row using AJAX.
$(".delete").on("click", function(){
var id = $(this).attr("id"); //get the id of the row
$.post("url_to_servlet_responsible_to_exclude_item", {
tId: id,
someOthetData: "anyData"
}).done(function(){
//if everything went ok,
//delete the div
$("div#" + id).remove();
});
})
First, I think you should not use the function on("click" in a loop.
You should use class delete for each button that you want to delete.
<button type="button" class="btn btn-default delete" data-id="<%=applicantDAO.viewApplicant().get(i).getApplicantID()%>" aria-label="Left Align">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
Outside of the loop, you call function on click
$(".delete").on("click", function () {
var id = $(this).attr("data-id"); //get the id of the row
$.post("url_to_servlet_responsible_to_exclude_item", {
tId: id,
someOtherData: "anyData"
}).done(function () {
//if everything went ok,
//delete the div
$("div#" + id).remove();
});
})
I have 3 progress bar on webpage from database data . When user click on load more 3 more progress bar get added from database data.
<div id="progressBar<?php echo $rec['cid'];?>" class="tiny-green"><div></div></div>
<!-- Some codes are here --->
...
....
.....
<?php
$prj= mysql_query("select * from campaign where uid=$uid");
$record = array();
while($row = mysql_fetch_assoc($prj)){
$record[] = $row;
}
?>
<script type="text/javascript">
<?php foreach($record as $rec){?>
progressBar(<?php $perc= $rec['value']*100/$rec['value1']; echo $perc;?>, $('#progressBar<?php echo $rec['cid'];?>'));
<?php } ?>
</script>
Below is javascript plugin
<script type="text/javascript" src="js/jquery.countdown.min.js"></script>
Now problem is when i add progress bar from load_more button(Which get data by load_more.php file and it insert it on index.php file). i can see the value but progress bar is not creating because code given above not loading after clicking on load_more.
So, i want to know is there any way i can reload that code only. So, wherever there is a progress bar control placed it get the display the bar.
update with some modifications, hope it will help you
$prj= mysql_query("select * from campaign where uid=$uid order by Closing_Date DESC Limit 0,1");
$result = array('data' => '', 'progress_bar' => array());
while($row = mysql_fetch_assoc($prj)) {
$result['data'] .= '<div class="col-sm-1 col-md-4 unique" id="'.$rec['cid'].'">
<div class="well">
<div class="media services-wrap55 wow fadeInDown">
<img class="img-responsive" src="'.$rec['poster'].'"><br>
<h4 class="media-heading">'.$rec['project_Name'].'</h4>
<p> by <i>'.$rec['user_name'].'</i></p>
<p> '.$rec['short_dis'].'</p>
<a class="" href="view_project/'.$rec['cid'].'/'.$rec['slug'].'">More ... </a>
<p>
<div id="progressBar'.$rec['cid'].'" class="tiny-green"><div></div></div>
<h6>'.($rec['view']*100/$rec['view2']).'% ( <i class="fa fa-user"></i>'.$rec['view']. ') '.$rec['view2'].' views.</h6>
</p>
<div class="counter-inner"> <div id="example1" data-countdown="'.date("m/d/Y h:i:s", strtotime($rec['Closing_Date'])).'"></div></div><p> <!-- Work on this -->
<div class="col-sm-11">
<div class="entry-meta">
<span><font color="#339933"><i class="fa fa-comment"></i> </font> '.$rec['comment'].' Comments </a></span><!-- Work on this -->
<span><font color="#339933"><i class="fa fa-thumbs-up"></i></font> '.$rec['up_count'].' </a></span>
<span><font color="#339933"><i class="fa fa-thumbs-down"></i></font> '.$rec['down_count'].' </a></span>
<span><font color="#339933"><i class="fa fa-star"></i> </font> '.$rec['fav_count'].' Fav </a></span>
</div>
</div>
</div>
</div>
</div>';
$result['progress_bar'][] = array('cid' => $rec['cid'], 'perc' => $rec['value'] * 100 / $rec['value1']);
}
$(document).ready(function() {
$('#more').click(function() {
var get_last_post_display = $('.unique-class:last').attr('id'); //get ip last <li>
$('#more').html('<img src="ajax-loader.gif"');
$.post('more_prj.php', 'last_id_post='+get_last_post_display, function(html) {
if(html.data) {
$('div').append(html.data);//$('.main-div') ?
$('#more').text('Load More Project'); //add text "Load More Post" to button again
for(i = 0; i < html.progress_bar.length; i++) {
progressBar(html.progress_bar[i]['perc'], $('#progressBar' + html.progress_bar[i]['cid']));
}
} else {
$('#more').text('No more Project to load'); // when last record add text "No more posts to load" to button.
}
}, 'json');
});
});