Codeigniter ajax call does not work properly - javascript

For example if I click 'vote up' button it successfully adds vote for the first post and displays the result in span element with class="rate_votes", but it also displays the same result in all the span elements with same class because of the following line:
$(".rate_votes").text(rate); //
How can I avoid that?
If I use
$(this).text(rate); //
it will not work properly because it does not know which span element to select. Could you help me please.
Here is my view:
<div>
<?php
foreach($results as $row){
$id = $row['id'];
$rate = $row['rate'];
?>
<div>
<?php
$data = array(
'name' => $id,
'class' => 'rate',
'content' => 'Vote Up'
);
echo form_button($data);
?>
<span class="rate_votes" >
<?php echo $rate; ?>
</span>
</div>
</div>
Here is my JS file:
$(document).ready(function() {
$(".rate").click(function(){
var self = this;
$(self).attr("disabled", true);
var id_like = $(self).attr("name");
$.post('filter/get_rate', { id_like: id_like }, function (data) {
var my_obj = data;
$.each(my_obj, function (i) {
var rate = my_obj[i].rate;
$(".rate_votes").text(rate); //
$(self).text("Voted!");
});
}, "json");
});
});

This has nothing to do with codeigniter :)
You bind the click event to an ID, #rate but that ID appears multiple times.
$data = array(
'name' => $id,
'id' => 'rate',
'content' => 'Vote Up'
);
echo form_button($data);
use a class instead.
When you select an ID that appears multiple times, only the first one is selected, thus only the first button works.
EDIT
Your comment sounds a bit strange, Given this code for example :
HTML:
<div class="foo">Foo</div>
<div class="foo">Foo</div>
<div class="foo">Foo</div>
<div class="foo">Foo</div>
Javascript/Jquery
$('.foo').click(function() { $(this).remove() });
The above code only removes the specific div being clicked, That is the event is only fired once and for that element only.
Doublecheck your javascript.

You have used:
$("#rate").click(function(){...})
Here "#rate" is an id and an id must be unique, use class like .rate. If you have multiple elements with same id on the page then only the first element of the page will be counted. So the following code is registering the click handler only on the first element with id rate:
$("#rate").click(function(){
//...
});
Give your elements a class instead, for example:
<button class='rate'>Rate</button>
<button class='rate'>Rate</button>
So this code will work on every button click:
$(".rate").click(function(){
var id_like = $(this).attr("name");
$(this).attr("disabled", true); // disables the current button
$('.rate').attr("disabled", true); // disable all the buttons with class rate
//...
});

Related

$(this).attr("data-id") returning undefined

I'm building a webshop and on every item there is a button to add that item to the shopping cart.
<?php
$i = 0;
$path = "../images/women/winter/winter1";
$lang = "description_".get_param();
if(!$result = $db->query("SELECT * FROM cloths;")){
die("There was an error running the query [".$db->error."]");
}
while($winter = $result->fetch_assoc()){
echo "<div class = \"boxsale $winter[image]\">
<img src = \"$path.jpg\"/>
<div class = \"test\"> $winter[$lang] </div>
<select>
<option>S</option>
<option>M</option>
<option>L</option>
<option>XL</option>
<option>XXL</option>
</select>
<button class = \"addToCart\" onclick = \"executeJS()\"> <i class = \"fa fa-shopping-cart\" data-id = \"$i\" aria-hidden=\"true\"></i></button>
</div>";
$i++;
}?>
</div>
when you click on the button the executeJS() in the last few lines gets called from a seperate file.
addToCart.js
function executeJS(){
var id = $(this).attr("data-id");
$.ajax( {
type: "GET",
url: "ajax.php?id=" + id + "&action=add"
})
.done(function(){
alert("Product has been added.");
});
}
i wanted to grab the data-id from the button that has been clicked, with
$(this).attr("data-id"); but all i get is a header that has undefined as data-id.
id=undefined&action=add
can anyone please point me in the right direction?
thanks
The problem is because $(this) is not correctly being applied to the element you're trying to access. When using a string based onclick handler (onclick="test()"), this refers to the window, and NOT the element you're trying to access.
function test() {
console.log(this.id);
}
Link
If you want to use the string based onclick notation, pass your element in explicitly, and do $(element).
<button class = \"addToCart\" onclick = \"executeJS(this)\" data-id = \"$i\" />
Javascript:
function executeJS(element){
var id = $(element).data('id');
...
Personally, skip the attr-id all together, and simply pass your id directly:
<button class = \"addToCart\" onclick = \"executeJS($id)\" />
It looks like this may be pointing to the window instead of the button.
You can fix this by manually looking for the button:
var id = $(".addToCart").attr("data-id");
This will only really work if you only have one button. What you should do is use jquery to attach the event to the button.
In your javascript:
$(".addToCart").click(function(e){
var id = $(e.target).attr("data-id");
$.ajax({
type: "GET",
url: "ajax.php?id=" + id + "&action=add"
})
.done(function(){
alert("Product has been added.");
});
})
The e.target refers to the button that is being clicked.
Use regular function (function(){}) instead of arrow function:
$(document).on("click",".deleteBtn",function(){
//Your Code
});
Since you're using jQuery, this is how you should be doing it. First, remove the inline event handler in your PHP (e.g. onclick = \"executeJS()\")
The other issue is that your buttons don't have a data attribute but their <i> children do.
Next, create your jQuery event handler, binding to the button. By doing this you can use $(this).find('i') to get the fontawesone <i> element and its data attribute, .attr("data-id"):
$('button.addToCart').click(function() {
var id = $(this).find('i').attr("data-id");
$.ajax({
type: "GET",
url: "ajax.php?id=" + id + "&action=add"
})
.done(function() {
alert("Product has been added.");
});
})
jsFiddle example

jQuery popover buttons (php)

I have a a button to generate presentations. I generate 8 presentation with one click, and then I can edit each one by clicking on its name. There I have another, smaller form. I want to have also some button there, that will let me choose which fields I want to edit. This applies to "place" part - you can specify the place, if you want to. I have a button to show/hide fields connected to place edition.
<div>
<?=
Html::button(Yii::t('app', 'Add new place'), [
'id' => "add-different-place-btn",
'class' => 'btn btn-success',
])
?>
<?=
Html::button(Yii::t('app', 'Delete new place'), [
'id' => "delete-different-place-btn",
'class' => 'btn btn-success',
])
?>
</div>
<br />
<div id="place-hidden-different">
<div id="place-name-hidden">
<?= $form->field($place, "[{$index}]name")->textInput()->label(Yii::t('app', 'New place')) ?>
</div>
<div id="place-city-hidden">
<?= $form->field($place, "[{$index}]city")->textInput() ?>
</div>
<div id="place-street-hidden">
<?= $form->field($place, "[{$index}]street")->textInput() ?>
</div>
<div id="place-postcode-hidden">
<?= $form->field($place, "[{$index}]post_code")->textInput() ?>
</div>
</div>
Then, in my jQuery part I figured out something like this. Notice that I'm really new to jQuery, so it can be something really obvious :)
$('.btn-popover-link').on('click', function () {
$(document).ready(function () {
$('#place-hidden-different').hide();
$('#delete-different-place-btn').hide();
$('#add-different-place-btn').on('click', function () {
$('#place-hidden-different').show();
$('#add-different-place-btn').hide();
$('#delete-different-place-btn').show();
});
$('#delete-different-place-btn').on('click', function () {
$('#place-hidden-different').hide();
$('#add-different-place-btn').show();
$('#delete-different-place-btn').hide();
});
});
});
But, instead of getting what I want to, I get things like that:
It looks ok. But it doesn't work. Nothing happens on clicking "Dodaj nowe miejsce" (Add new place). Morover, in other presentation I get full variety of that form - example below. None of the buttons is working at all, in some popovers there are no buttons at all, in some just not working.
What can cause this situation?
If I get it well, you are using the same ID #add-different-place-btn for each of the 8 presentations button.
If this is right, the code is working as expected: IDs must be unique !
You should move to a class selector like you did with .btn-popover-link.
Also you should move $('.btn-popover-link').on('click', function () {}); inside the $(document).on("ready", function() { ... here ... });.
Even better with $(window).on("load", function() {}); but it depends on the kind of code you are running.

If statement cakephp input value and run a javascript code

I am trying to make an if statement with cakePHP but I'm really an amateur. I checked the cookbook and stackoverflow but couldn't find it. (using 2.x.x version of cake)
So what I'm trying to do is:- if the ticket-1-amount is not zero, remove the invisible class.
Something I tried but didn't work:-
if ( $('#ListTypeTicket-1-amount').val() != '' ) {
$("#invisibleBox").removeClass("invisible");
}
Also tried this:-
if (empty($this->request->data ['ticket-1-amount'] != 0)) {
echo '$("#invisibleBox").removeClass("invisible");</script>';
} ;
My cakePHP form:-
<?=$this->Form->input(
'ticket-1-amount',
array('label' => false,
'class' => 'ticket-1-amount',
'id' => 'ticket-1-amount')
); ?>
This is the actual div
<div id='invisibleBox' class="invisible">
..........
</div>
Keep things simple, Just try:
<div id='invisibleBox' class="<?php if($this->request->data['ticket-1-amount'] == 0) {echo 'invisible'}; ?>">
..........
</div>
Create a JavaScript file and put the code below inside it.
App = {
init: function () {
this.checkTicketAmount();
},
checkTicketAmount: function(){
if ($('#ticket-1-amount').val() != '0') {
$("#invisibleBox").removeClass("invisible");
}
}
};
$(document).ready(function () {
App.init();
});
After the page is loaded, jQuery will check the ticket amount value and remove the invisible class, or not.

Automatic scrolling when clicking my submit button

So on my custom module that I've created, there's a submit button (form defined in php) but it already acquires an action where it calls a callback function to trigger the display of some information regarding a certain barcode right below it.
All I want to do is add some code that will allow my submit button to also trigger an automatic scroll down without a link/anchor (because I want the SUBMIT BUTTON to acquire that action, not another link) so that the user doesn't have to scroll down to view the information.
The reason I'm avoiding the link/anchor option is because I just dont want to have a separate entity that needs to be clicked in order to scroll down. I want the scroll to happen right when i click my submit button. Unless a link can be combined with a button? Thanks!
My PHP submit button form:
//submit button that uses ajax (to display whats in callback)
$form['submit_button'] = array(
'#type'=> 'submit',
'#value'=> t('Submit'),
'#ajax' => array( //no need to refresh the page bc ajax
'callback' => '_ibbr_inv_after_callback', //callback
),
'#suffix' => "<div id='after_div'><br></div>
<div id='after_status'></div>",
);
return $form;
My PHP callback function:
//function for submit button callback
function _ibbr_inv_after_callback($form, $form_state) {
$selector = '#after_div';
$commands = array();
$query = new EntityFieldQuery();
$entities = $query->entityCondition('entity_type', 'node')
->propertyCondition('type', 'eq')
->propertyCondition('title', $form_state['input']['barcode'])
->propertyCondition('status', 1)
->range(0,1)
->execute();
//If this barcode is found in database
if (!empty($entities['node'])) {
$node = node_load(array_shift(array_keys($entities['node'])));
//Load fields from returned equipment item
$room = taxonomy_term_load($node->field_eq_room['und'][0]['tid']);
$desc = $node->field_eq_description['und'][0]['value'];
$manu = $node->field_eq_mfr['und'][0]['value'];
$model = $node->field_eq_modelno['und'][0]['value'];
$serial = $node->field_eq_serial['und'][0]['value'];
//displaying all the components of the specific barcode
$info = "<div id='after_div'><b>Title</b>: $node->title<br>
<b>Description</b>: $desc<br>
<b>Manufacturer</b>: $manu<br>
<b>Room</b>: $room->name<br>
<b>Model Number:</b> $model<br>
<b>Serial Number:</b> $serial<br></div>";
//Displaying the Confirm and Flag buttons
$commands[] = ajax_command_replace($selector, $info);
$commands[] = ajax_command_replace("#after_status", "<div id='after_status'> <button id = 'confirm' type = 'submit' name = 'Confirm' value = 'Confirm'> Confirm</button><button id = 'Flag' type = 'submit' name = 'flag' value = 'flag'>Flag </button> </div>");
//$commands[] = ajax_command_invoke("#after_div", 'animate', array("{scrollTop: top}",1000));
//If this barcode is not found in the database
}else {
//Displaying the Add button and "Item not found" ONLY IF this entity is empty (meaning barcode was not found in database)
$commands[] = ajax_command_replace($selector, "<div id = 'after_div'>Item not found.</div>");
$commands[] = ajax_command_replace("#after_status", "<div id='after_status'><button id = 'add' type = 'submit' name = 'Add' value = 'Add'>Add new item</button></div>");
}
return array('#type' => 'ajax', '#commands' => $commands);
}//end _ibbr_inv_after_callback
With javascript you can make your submit button to jump to any HTML element on the page, without link/anchor. Next example has two buttons, when clicked, buttons will scroll down to different points of the page :
<html>
<head>
<script type="text/javascript">
function godown ()
{ document.getElementById("down").scrollIntoView(); // JUMP TO DIV "DOWN".
}
function gobottom ()
{ document.getElementById("bottom").scrollIntoView(); // JUMP TO DIV "BOTTOM".
}
</script>
</head>
<body>
<button onclick="godown()">Click to go down</button>
<button onclick="gobottom()">Click to go bottom</button>
<br/>1<br/>2<br/>3<br/>4<br/>5<br/>6<br/>7<br/>8<br/>9<br/>0<br/>
<br/>1<br/>2<br/>3<br/>4<br/>5<br/>6<br/>7<br/>8<br/>9<br/>0<br/>
<br/>1<br/>2<br/>3<br/>4<br/>5<br/>6<br/>7<br/>8<br/>9<br/>0<br/>
<br/>1<br/>2<br/>3<br/>4<br/>5<br/>6<br/>7<br/>8<br/>9<br/>0<br/>
<br/>1<br/>2<br/>3<br/>4<br/>5<br/>6<br/>7<br/>8<br/>9<br/>0<br/>
<br/>1<br/>2<br/>3<br/>4<br/>5<br/>6<br/>7<br/>8<br/>9<br/>0<br/>
<br/>1<br/>2<br/>3<br/>4<br/>5<br/>6<br/>7<br/>8<br/>9<br/>0<br/>
<br/>1<br/>2<br/>3<br/>4<br/>5<br/>6<br/>7<br/>8<br/>9<br/>0<br/>
<br/>1<br/>2<br/>3<br/>4<br/>5<br/>6<br/>7<br/>8<br/>9<br/>0<br/>
<div id="down">You are down!</div>
<br/>a<br/>b<br/>c<br/>d<br/>e<br/>f<br/>g<br/>h<br/>i<br/>j<br/>
<br/>a<br/>b<br/>c<br/>d<br/>e<br/>f<br/>g<br/>h<br/>i<br/>j<br/>
<br/>a<br/>b<br/>c<br/>d<br/>e<br/>f<br/>g<br/>h<br/>i<br/>j<br/>
<br/>a<br/>b<br/>c<br/>d<br/>e<br/>f<br/>g<br/>h<br/>i<br/>j<br/>
<br/>a<br/>b<br/>c<br/>d<br/>e<br/>f<br/>g<br/>h<br/>i<br/>j<br/>
<br/>a<br/>b<br/>c<br/>d<br/>e<br/>f<br/>g<br/>h<br/>i<br/>j<br/>
<br/>a<br/>b<br/>c<br/>d<br/>e<br/>f<br/>g<br/>h<br/>i<br/>j<br/>
<br/>a<br/>b<br/>c<br/>d<br/>e<br/>f<br/>g<br/>h<br/>i<br/>j<br/>
<br/>a<br/>b<br/>c<br/>d<br/>e<br/>f<br/>g<br/>h<br/>i<br/>j<br/>
<div id="bottom">You are at the bottom!</div>
</body>
</html>
You just insert your information inside a <div> (or a table, or anything you want), give it an "id", and you will be able to scroll down to it with javascript method ".scrollIntoView()".
Copy/paste previous code in a file and save it as HTML, then open it in your browser.
Edit #1 : add some javascript code with PHP right after you fill "after_div" :
$info = "<div id='after_div'><b>Title</b>: $node->title<br>
<b>Description</b>: $desc<br>
<b>Manufacturer</b>: $manu<br>
<b>Room</b>: $room->name<br>
<b>Model Number:</b> $model<br>
<b>Serial Number:</b> $serial<br></div>" .
"<script type='text/javascript'>" .
"document.getElementById('after_div').scrollIntoView();" .
"</script>";
Edit #2 : replace this line :
$commands[] = ajax_command_replace($selector, "<div id = 'after_div'>Item not found.</div>");
by this next one :
$body = "<div id = 'after_div'>Item not found.</div>" .
"<script type='text/javascript'>" .
"document.getElementById('after_div').scrollIntoView();" .
"</script>";
$commands[] = ajax_command_replace($selector, $body);

Jquery click function not working when using AJAX

this is my html code
<input type="hidden" value="<?php echo $rslt['id'] ?>" id="res_id" /> <!-- this line catch post id -->
<div id="likeSec">
<h4><?php echo $rslt['likes'] ?> People Like this</h4> <!-- this line show total likes -->
<?php
$kol=mysql_query("SELECT * FROM tbl_like_recipe WHERE res_id='".$rslt['id']."' && user_id='".$_SESSION['member_email']."'");
$num_rows = mysql_num_rows($kol); // this query check this user already like this post or not
if($num_rows==0){ // if not liked already show like image
?>
<div id="like" style="float:right;"><img src="images/like.png" width="45" /></div>
<?php
}else{ // if already like show unlike image
?>
<div id="dislike" style="float:right;"><img src="images/unlike.png" width="45" /></div>
<?php } ?>
</div>
and this my script
<script>
$(document).ready(function(){
$("#like").click(function(){
var res_id=$("#res_id").val();
$.post("like_recipe_prosses.php",{'data':res_id},function(cbd){
$("#likeSec *").remove();
$("#likeSec").html(cbd)
})
})
$("#dislike").click(function(){
var res_id=$("#res_id").val();
$.post("dislike_recipe_prosses.php",{'data':res_id},function(cbd){
$("#likeSec *").remove();
$("#likeSec").html(cbd)
})
})
})
</script>
When I click 'like' I see it becomes 'Unlike', but if I click on 'Unlike' it doesn't work.
If I then refresh the page and click 'Unlike', it becomes 'Like', but I can not click 'Like' again to make it 'Unlike' again.
What did I do wrong here? please help me someone.
You are generating dynamic elements in your DOM, thus the click event wont be attached due to the lack of delegation, in order to make this work, try the following:
$("#likeSec").delegate('#like', 'click', function(){
var res_id=$("#res_id").val();
$.post("like_recipe_prosses.php",{'data':res_id},function(cbd){
$("#likeSec *").remove();
$("#likeSec").html(cbd)
})
})
$("#likeSec").delegate('#dislike', 'click', function(){
var res_id=$("#res_id").val();
$.post("dislike_recipe_prosses.php",{'data':res_id},function(cbd){
$("#likeSec *").remove();
$("#likeSec").html(cbd)
})
})
Try this
$('#likeSec').on('click','yourdiv',function(){
//Your Code
});
When you receive ajax response, you replace original HTML elements which had events attached with new HTML. Use .on to attach delegated events:
$("#likeSec").on("click", "#like", function(){
var res_id=$("#res_id").val();
$.post("like_recipe_prosses.php",{'data':res_id},function(cbd){
$("#likeSec").html(cbd)
})
})
$("#likeSec").on("click", "#dislike", function(){
var res_id=$("#res_id").val();
$.post("dislike_recipe_prosses.php",{'data':res_id},function(cbd){
$("#likeSec").html(cbd)
})
})

Categories