Laravel ajax request not working for a foreach loop - javascript

I have collected some data in my controller.Now In my view,I have showed them inside an unordered list (ul) as a link.
<ul>
<li><a>....</a></li>
</ul>
Now When I am trying to fire an ajax request,only last data (i.e,Last link in listed items) is responding to the ajax request.The Ajax script is not inside the foreach loop.Do I have to place the ajax script inside the foreach loop.Then,for each data there will be a script.won't it create a problem?
<ul>
#foreach ($brands as $brand)
<li class='n1'>{{$brand->brand}}</li>
#endforeach
</ul>
my ajax script:
<script>
$('#{{$brand->brand}}').on('click',function(e){
e.preventDefault();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type:"POST",
url:'/userproduct',
data: { value: $('#{{$brand->brand}}').attr('href')},
success:function(data) {
console.log(data);
}
});
});
</script>
In My Controller
public function userproduct(Request $request){
$value=$request->input('value');
return Response::JSON($value);
}

IMO, {{$brand->brand}} as "id" doesn't make sense. You can do it like,
id="product-{{$brand->brand}}"
As you're just writing $('#{{$brand->brand}}').on('click',function(e){}); this means that, you're registering only one node.
How to overcome this?
Apply a specific class for those links. register the click event with that class. Use, HTML5 data-* api to get the link and like so. That's it.

At first, made the following changes in a elements for example:
<a class="brand" href="{{url('userproduct')}}" data-id="{{$brand->id}}">
{{$brand->brand}}
</a>
Then use the following code:
$(document).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$('a.brand').on('click',function(e) {
var el = $(this);
$.ajax({
type: "POST",
url: el.attr('href'),
data: { value: el.attr('data-id')},
success: function(data) {
console.log(data);
}
});
e.preventDefault();
});
});
This should work but make sure that, you've also declared a route using post method for userproduct, for example:
Route::post('/userproduct', 'SomeController#handlerMethodName');
Check the browser console to find out error details if it doesn't work and try to solve the issues.The workflow is okay and should work if everything went well.
Note: There are other ways to do it (using different code/approach) but this is a simplified code depending on your code given in the question. For example, I could have used the ul to register the event handler using event delegation but this'll work as well.

You are using the id of the last item in your ajax. That's why only last link in listed items is responding to the ajax request. Use class instead of id like this:
<li class='n1'><a class="myclass" href="{{$brand->id}}">{{$brand->brand}}</a></li>
JS:
<script>
$('.myclass').on('click', function(e) {
e.preventDefault();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
method: "POST",
url: '/userproduct',
data: {
value: $(this).attr('href')
},
success: function(data) {
console.log(1);
}
});
});
</script>
It should work.

Related

How to generate a button with its own js function?

Well I have data retrieved from ajax, I need to parse it in order to generate inputs with different <input> values. While clicking on <a> that should get near standing input value and go to ajax
<script type="text/javascript">
function proceed() {
var ID = document.getElementById('btnid').value;//probably that`s the wort way, because all of `<a>` buttons would have same id
//ajax with ID to proceed further
}
$.ajax({
async: false,
type: "POST",
url: "../api/",
data: {'data': "mydata"},
dataType: 'JSON',
complete: function (res) {
for(var i = 0; i < 10; i++) {
document.getElementById('nie').innerHTML = "
<ul class=\"somec\">
<li class=\"liclass\">
</input id=\"btnid\" value=\""+res.response[i].animal+"\" class=\"thatclass\" onclick=\"proceed();\"></input>//different values
<a id="clicker" onclick="proceed()"></a>//clickable link
</li>
</ul>
";
}
});
</script>
<html>
<div id="nie">
</div>
</html>
Any help or advises for solution ?
You cannot have more than one id in a single DOM -- only one unique id is allowed. Since jQuery is used here, you can take advantages of the other methods and API it provides.
First of all, I would move the loop to success handler of $.ajax because that ensures that I have data returned from the server.
As for "appending" input and anchor pairs, use $.append. What you're currently doing is just updating #nie with the last element's data in the loop.
For events, delegate the clicks on anchors. This is better because you might continue adding more elements, so you have to go through binding them to an event.
And please, don't set async to false in $.ajax settings. This has unexpected results and makes the browser slow to point that freezes and crashes. jQuery ajax async: false causes a strange warning?
$(function(){
var $nie = $('#nie');
// Delegate the click event
$(document).on('click', '.clicker' function(){
var id = $(this).siblings('input').val();
// Use id in upcoming AJAX request.
});
$.ajax({
type: "POST",
url: "../api/",
data: {'data': "mydata"},
dataType: 'JSON',
success: function (res){
$.each(res.response, function(i, r){
$nie.appeand('<ul class="somec">\
<li class="liclass">\
<input value="'+ r.animal+ '" class="thatclass"/>\
<a class="clicker"></a>\
</li>\
</ul>');
});
}
});
});

Turning jquery into an includable, callable function

I'm so frustrated! As an ok PHP developer I can't get my head around the simplist of jquery problems!
I have recently moved my HTML jquery include to the end of the HTML body, instead of in the head to improve google pagespeed score.
This has broken some jquery which is used for simple comment voting. This was written badly as it repeats for every comment.
<div id="voterow-19907" class="commentfooter">UP</a> | <a id="comment-vote-down-19907" href="#" rel="nofollow">DOWN</a></div>
<script>
$("#comment-vote-up-19907").click(function() {
$.ajax({
type: "GET",
url: "/ajax.php",
data: "a=rv&v=19907&d=up",
success: function(data){
$("#voterow-19907").text("Thank you for your vote")
}
});
return false;
});
$("#comment-vote-down-19907").click(function() {
$.ajax({
type: "GET",
url: "/ajax.php",
data: "a=rv&v=19907&d=down",
success: function(data){
$("#voterow-19907").text("Thank you for your vote")
}
});
return false;
});
</script>
Since moving the jquery include to the bottom of the page this naturally doesn't work.
What I'm trying to do is turn the above code into a mini function I can include after the jquery include, then pass the ID and VOTE-DIRECTION to the function from the HTML a hrefs using the jquery DATA- attribute.
Any help would be greatly appreciated. I'm running out of hair!
I think, repeated codes will hurt your page than placement of JQuery file.
You can solve this problem using more general event listener. Remove all listeners inside code (all of them) and append the code below after Jquery include.
$('[id^=comment-vote]').click(function() {
var elementId = $(this).attr('id');
var elementIdParts = elementId.split("-");
var voteType = elementIdParts[2];
var id = elementIdParts[3];
$.ajax({
type: "GET",
url: "/ajax.php",
data: "a=rv&v="+id+"&d="+voteType,
success: function(data){
$("#voterow-"+id).text("Thank you for your vote")
}
});
return false;
});
$('[id^=comment-vote]") selects all elements which have id starting with "comment-vote". If user clicks one of these elements, event handler gets id of elements, split into parts like "comment", "vote", "up", "19900". 2nd part is voteType and 3rd part is ID of row. We can use these variables while generating/operating AJAX request.
I didn't try the code but the idea behind that would be beneficial for you.
To really give a great working answer, I would need to see your an example page / the exact structure of your html, but here's what I have for you.
In a script file that you include after jQuery, you can include something similar to the below code assuming your html is as follows:
<div id="voterow-1" class="voterow">
<p class="voteresult"></p>
<a class="upvote" href="#" rel="nofollow">UP</a>
<a class="downvote" href="#" rel="nofollow">DOWN</a>
</div>
<div id="voterow-2" class="voterow">
<p class="voteresult"></p>
<a class="upvote" href="#" rel="nofollow">UP</a>
<a class="downvote" href="#" rel="nofollow">DOWN</a>
</div>
Having the class of upvote and downvote makes it easy to target these elements in jQuery:
// After jQuery is loaded, the function passed to ready() will be called
$(document).ready(function () {
// bind a click event to every direct child with the upvote class of an element with the voterow class
$('.voterow > .upvote').click(function (event) {
// get the voterow parent element
var $parent = $(event.target).parent();
// use regex to strip the id number from the id attribute of the parent
var id = parseInt($parent.attr('id').match(/^voterow-(\d+)/)[1]);
// call your ajax function
vote(id, 'up', $parent.find('.voteresult');
});
$('.voterow > .downvote').click(function (event) {
var $parent = $(event.target).parent();
var id = parseInt($parent.attr('id').match(/^voterow-(\d+)/)[1]);
vote(id, 'down', $parent.find('.voteresult');
});
function vote(id, direction, $resultElement) {
$.ajax({
type: "GET",
url: "/ajax.php",
// here we have the id and the direction needed to make the ajax call
data: "a=rv&v=" + id + "&d=" + direction,
success: function(data){
$resultElement.text("Thank you for your vote")
}
});
}
});
Here is a demo: https://plnkr.co/edit/ECL376hZ3NOz8pBVpBMW?p=preview

Run JS after div contents loaded from AJAX

There are a ton of proposed answers to my question, but even with all the answers I have found, I can not seem to get any to work. I can make the JS work by adding a delay in execution of the code, but I can't rely on a delay to execute the JS after div has finished loading it's HTML.
I'm creating a page where users can search for an item, and the results are displayed in a div using AJAX. I need some JS to run after the div's html has finished loading. Some of the results data will be hidden until a user clicks on it. The JS code to accomplish this is what I am trying to run once the div finishes loading.
I have tried the following extensively with no luck anywhere:
.load
.ajaxComplete
.complete
.success
.done
Document.ready
I'm sure there are a few others as well, but my brain is just too beat up from dealing with this to remember everything I've tried so far.
My HTML:
<form name ="CardName" method="post" action="">
<div "class="w2ui-field">
<div> <input type="list" Name="CardName" id="CardName" style="width: 80%;"></div>
</div>
<div class="w2ui-buttons">
<input type="submit" name="search" style="clear: both; width:80%" value="Search" class="btn">
</div>
</form>
<div class="Results" id="Results" name="Results"></div>
My JS:
$(function() {
$("#CardSearch").bind('submit',function() {
var value = $('#CardName').val();
$.ajax({
method: "POST",
url: "synergies.php",
data: {value}
})
.success(function(data) {
$("#Results").html(data);
})
.complete(function() {
alert("div updated!"); //Trying to run JS code AFTER div finishes loading
});
return false;
});
});
If there is anything else that could help with this request just let me know!
Thanks in advance!
Note that success and failure are options that you should provide to the $.ajax call, not the returned promise. Also, bind is deprecated in favour of on since jQuery 1.7. Finally, you need to give the value that you're posting to your PHP page a key so that it can be retrieved via $_POST. Try this:
$("#CardSearch").on('submit', function(e) {
e.preventDefault();
$.ajax({
method: "POST",
url: "synergies.php",
data: {
CardName: $('#CardName').val()
},
success: function(data) {
$("#Results").html(data);
},
complete: function() {
alert("div updated!"); //Trying to run JS code AFTER div finishes loading
}
})
});
You can then retrieve the value sent in your synergies.php file using $_POST['CardName'].
If you prefer to use the method provided by the returned promise, you can do that like the below, although the result is identical.
$("#CardSearch").on('submit', function(e) {
e.preventDefault();
$.ajax({
method: "POST",
url: "synergies.php",
data: {
CardName: $('#CardName').val()
}
}).done(function(data) {
$("#Results").html(data);
}).always(function() {
alert("div updated!");
})
});
you can try Synchronous Ajax request, demo code is given below:
$(function() {
$("#CardSearch").bind('submit',function() {
e.preventDefault();
sendData = $('#CardName').val();
reqUrl = "synergies.php";
// this will wait until server request complete
var ajaxOpt = AjaxSyncRequest(reqUrl, sendData);
// after complete server request
ajaxOpt.done(function(data) {
$("#Results").html(data);
});
});
});
function AjaxSyncRequest(reqUrl, sendData) {
var ajaxData = $.ajax({
method: "POST",
url: reqUrl,
data: {
data: sendData
}
});
return ajaxData;
}

Javascript breaks when I update html with Ajax

Having a problem with a webapp i've been working on lately, and it has to do with ajax reloading breaking javascript.
I have the following Ajax Call
$.ajax({
type: "POST",
url: "/sortByIngredient/",
data: JSON.stringify(
{
selectedIngredients: tempDict
}),
contentType: "application/json; charset=utf-8",
success: function(data){
var curList = $("#drinkList").contents();
console.log(curList);
$("#drinkList").empty()
$("#drinkList").append(data)
and the following Html UL
<div id = "drinkList" class="d-list">
<ul>
<li id='someID'>some Item</li>
<li id='someID2'>some Item2</li>
</ul>
</div>
I also have a jQuery callback set to activate on clicked list items. On initial loading, all works well. Once the ajax call occurs, and replaces the contents of #drinkList with another list, formatted identically. In case anyone is curious, here is the onClick callback:
$("li").click(function()
{
window.currentDrink = $(this).attr("id");
console.log(window.currentDrink);
$.ajax({
url: "/getDrink/" + $(this).attr("id"),
type: "get",
success: function(data){
$("#ingDiv").html(data);
}
});
});
After I make that Ajax call, the list modifies correctly, but after that, no more javascript seems to work. For example,the console.log is not called when i click on a list item, and the proper view doesnt update(#ingDiv, as shown in the above call)
Is my changing the HTML through Ajax breaking the javascript somehow?
Am I missing something obvious? If it isn't clear already, I am not a web developer.
use event delegation like this -
$('#drinkList').on('click','li',function(){
// do your stuff here
});
As you are not a web developer - This is what your code should look after changes
$('#drinkList').on('click', 'li', function () {
window.currentDrink = $(this).attr("id");
console.log(window.currentDrink);
$.ajax({
url: "/getDrink/" + $(this).attr("id"),
type: "get",
success: function (data) {
$("#ingDiv").html(data);
}
});
});
http://learn.jquery.com/events/event-delegation/
http://api.jquery.com/on/

$.ajax interfering with .hide() and .show() Jquery in this script

(In Firefox and IE9 it doesn't work. In Chrome, this works)
If I remove the ajax, the hide / show JQuery works. Any solutions?
<form id="ppform" action="blah.asp" method="post">
<div id="saleload">Blah</div>
<button id="sendbutton">Send</button>
</form>
$(document).ready(function(){
$('#saleload').hide();
$('#sendbutton').click(function() {
$('#saleload').show();
$.ajax({
type: "POST",
url: /blah/blah.asp,
data: reqBody,
dataType: "json",
success:function(data,textStatus){
if (data.redirect) {
window.location.href = data.redirect;
}else{
$("#ppform").replaceWith(data.form);
}
}
});
});
});
This line:
$("#ppform").replaceWith(data.form);
is replacing the whole form contents with the response from your Ajax request. This means the click handler you setup will be gone too, because #sendbutton will be gone. Even if you have another button with the same ID inside data.form, it won't work. You have to use event delegation instead:
$(document).ready(function(){
$('#saleload').hide();
$(document).on('click', '#sendbutton', function(){
$('#saleload').show();
$.ajax({
type: "POST",
url: "/blah/blah.asp",
data: reqBody,
dataType: "json",
success:function(data,textStatus){
if (data.redirect) {
window.location.href = data.redirect;
} else {
$("#ppform").replaceWith(data.form);
}
}
});
});
});
Also: you seem to be posting an undefined variable reqBody to your server, and, as lonesomeday said above, you were missing quotes around the URL.
The obvious reason is that there is an error with your Javascript that causes the whole section not to execute. Quickly looking through your code shows this line:
url: /blah/blah.asp,
Strings need to be enclosed in quotation marks:
url: "/blah/blah.asp",

Categories

Resources