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/
Related
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>');
});
}
});
});
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.
I'm currently working on a project using Laravel platform.
I'm trying to delete data from a model asynchronously using ajax. And when all is done my data should be removed from the table. My code runs perfectly, data are being removed from my database , yet "tr" elements arent really faded or removed. Here is my code :
ajax sucess not really working.
$(document).on('click', '.btn-remove-interview' , function() {
var id = $(this).attr('data-interview-id');
$.ajax({
url: './manage/interviews/destroy/'+id ,
type: 'post',
dataType: 'json',
data: id,
success: function (data) {
$(this).parents("tr").remove();
}
});
});
Use
$(this).closest('tr').remove();
Instead of
$(this).parents("tr").remove();
The problem is that the success function callback within your ajax request no long refers to the button when you use this. You need to get an explicit variable to the button if you want to use it.
$(document).on('click', '.btn-remove-interview' , function() {
// Get this button as a variable so we can use it later
var el = $(this);
var id = $(this).attr('data-interview-id');
$.ajax({
url: './manage/interviews/destroy/'+id ,
type: 'post',
dataType: 'json',
data: id,
success: function (data) {
$(el).parents("tr").remove();
}
});
});
Solution was by removing dataType json . My function doesnt return any data .
(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",
I'm using the plugin jquery-tmpl. Is there a way to specify a callback after a template is run? I want to do something like
<script id='itemTemplate' type='text/html'>
<li class="item" id=${timestampMs}>
<span class="content">${content}</span>
</li>
${processItem($('#' + timestampMs))}
</script>
Where processItem does something to the <li> element that just got generated. As it's written, though, the element doesn't exist at the time processItem is called.
Here's how I run the template:
// Make the AJAX call to the service
$.ajax({
dataType: "json",
url: "/getItems",
success: function(data) {
// fill out template from json
$('#itemTemplate').tmpl(data).appendTo('#container');
}
});
Thanks!
After you call .tmpl, you have nodes that you can act upon, so you can do this:
$.ajax({
dataType: "json",
url: "/getItems",
success: function(data) {
// fill out template from json
$('#itemTemplate').tmpl(data).each(function (index) {
processItem($(this))
}).appendTo('#container');
}
});
That's similar to your workaround, but you shouldn't need to reselect the items, and you should be able to chain the call.
Here's the workaround I'm using for now:
$.ajax({
dataType: "json",
url: "/getItems",
success: function(data) {
// fill out template from json
$('#itemTemplate').tmpl(data).appendTo('#container');
// now process the new events
$('#container .item').each(function (index) {
processItem($(this))
});
}
});