Ajax post executed twice and adding up - ajax

I'm facing an issue with ajax that several users here also encountered but the proposed solution do not seem to work for my case.
in my index.php file, I have:
<pre>
<script>
function ButtonManager()
{
$( "button" ).click(function()
{
var context = $(this).attr('type');
var page_type = $(this).attr('page');
var referrer = $(this).attr('referrer');
var form_type = $(this).attr('form');
var object_id = $(this).attr('object');
var postData = 'page_type='+page_type+'&form_type='+form_type+'&referrer='+referrer+'&id='+object_id;
$( '#indicator' ).css( "display", "block" );
if (context == 'post_form')
{
var formData = $('#submit_content').serialize();
postData = postData+'&context=post_form&'+formData;
}
if ((context == 'load_form') || (context == 'filter_form'))
{
postData = postData +'&context=load_form';
if (context == 'filter_form')
{
var filter1 = $('select[name=filter1]').val();
var filter2 = $('select[name=filter2]').val();
var filter3 = $('select[name=filter3]').val();
postData = postData + '&filter1='+filter1+'&filter2='+filter2+'&filter3='+filter3;
}
}
$.ajax
({
type: 'POST',
url: 'php/sl.php',
data: postData,
cache: false,
async: false,
dataType: 'html',
success: function(result)
{
ManageLayer(form_type+'_content');
$('#'+form_type+'_content').html(result);
$( '#indicator' ).css( "display", "none" );
},
error: function(XMLHttpRequest, textStatus, errorThrown)
{
alert(XMLHttpRequest.status);
alert(XMLHttpRequest.responseText);
$( '#indicator' ).css( "display", "none" );
},
});
});
}
</script>
<button type="load_form" page="home" referrer="navigation" form="edit" object="">test</button>
</pre>
when a click on the test button, the script calls sl.php to retrieve some html with other buttons in it.
in the output I get from the server I have added:
<pre>
<script>
var myvar=ButtonManager();
</script>
<button type="post_form" page="home" referrer="navigation" form="edit" object="">test2</button>
</pre>
The goal of the ButtonManager function is to manage all my buttons in one function so it needs to be available/known everywhere (in index.php where it's loaded and in all the output I can get from sl.php).
I have added the var myvar=ButtonManager() line because it's the only way I have found to make sure the function is known by the server output. The drawback is that the function is executed multiple times instead of one even if I don't click on the test2 button.
So I'm looking either for a way to prevent my function from being executed multiple times or an alternative to make the function available everywhere.
I don't know what approach would be the best, I'm a casual developper programming for fun and javascript / ajax is not the language I know the best.
Thanks
Laurent

I got the answer from another forum but I wanted to share it in case others are having the same problem.
Code to be used should be like this:
<pre>
$( document ).on("click", "button", function() {
</pre>
It makes the function available to objects that do not exist yet.

Related

jquery autocomplete is now working properly

I am working on jquery autocomplete in mvc platform. Now, my question is that in some textbox data autocomplete is working properly while in some textbox data autocomplete is not working properly.
For more clear, lets see the image of autocomplete task
now as per the image when I write the R word, I am getting the suggestion list of related R word.
now as per the second image I have written the whole word but still suggestion is not display.
Here is my code,
View
<input type="text" id="CustomerName" name="CustomerName" required data-provide="typeahead" class="typeahead search-query form-control autocomplete"
placeholder="Customer Name" />
<script>
$(document).ready(function () {
$.ajax({
url: "/ServiceJob/CustomerSerchAutoComplete",
method: "GET",
dataType: "json",
minLength: 2,
multiple: true,
success: function (data) {
/*initiate the autocomplete function on the "myInput" element, and pass along the countries array as possible autocomplete values:*/
//autocomplete(document.getElementById("CustomerName"), data.data);
$('#CustomerName').autocomplete({ source: data.data, minLength: 2, multiple: true });
}
});
});
</script>
Controller
[HttpGet]
public IActionResult CustomerSerchAutoComplete()
{
var customers = _Db.Ledger.Where(x => x.LedgerTypeId == (int)LedgerType.Customer).ToList();
var result = (from n in customers
select new
{
kk = n.Name.ToUpper()
}).ToList();
return Json(new { data = result });
}
As you are getting
Uncaught TypeError: Cannot read property 'substr' of undefined
For this error you should check that data is not null.
success: function (data) {
if(data != null)
{
autocomplete(document.getElementById("CustomerName"), data.data);
}
}

Kendo Tooltip is empty

dI use a kendo tooltip on cells of a column of a kendo grid but the content of the tooltip is empty.
When I use the chrome debugger, values are correctly set but there is nothing in my tooltip.
$("#gri").kendoTooltip({
filter: "span.tooltip",
position: "right",
content: function (e) {
var tooltipHtml;
$.ajax({
url: ".." + appBaseUrl + "api/Infobulle?id=" + $(e.target[0]).attr("id"),
contentType: "application/json",
dataType: "json",
data: {},
type: "GET",
async: false
}).done(function (data) { // data.Result is a JSON object from the server with details for the row
if (!data.HasErrors) {
var result = data.Data;
tooltipHtml = "Identifiant : " + result.identifiant;
} else {
tooltipHtml = "Une erreur est survenue";
}
// set tooltip content here (done callback of the ajax req)
e.sender.content.html(tooltipHtml);
});
}
Any idea ? Why it is empty ?
After looking at the dev's answer on telerik forums, i found out that you need to do something like
content: function(){
var result = "";
$.ajax({url: "https://jsonplaceholder.typicode.com/todos/1", async:false , success: function(response){
result = response.title
}});
return result;
}
changing directly with e.sender.content.html() won't work, instead we have to return the value. And i tried several approach :
i tried mimick ajax call with setTimeOut, returning string inside it or using e.sender.content.html() wont work
i tried to use content.url ( the only minus i still don't know how to modify the response, i display the whole response)
the third one i tried to use the dev's answer from here
AND check my example in dojo for working example, hover over the third try

Using ajax to update the currently page with Laravel

I have this ajax inside my file.php (It hits the success callback):
<script type="text/javascript">
$('#selectSemestres').change(function(obj){
var anoSemestre = $(this).val();
$.ajax({
type: 'GET',
url: '{{ route('professor') }}',
data: {anoSemestre: anoSemestre},
success: function(data){
console.log(data);
}
});
})
</script>
Now on my Controller:
public function getProfessorList()
{
$professor = Professor::all();
$ano_semestre = isset($_GET['anoSemestre']) ? $_GET['anoSemestre'] : Horario::first()->distinct()->pluck('ano_semestre');
$semestres = Horario::distinct()->select('ano_semestre')->get()->toArray();
return View::make('professor', compact('professor', 'semestres', 'ano_semestre'));
}
What I want to do:
I have a LIST with professor and their disciplines. What I need to do is:
Whenever I change the value of that select box, I just remake the function with the new parameter.
I'm trying to use ajax to remake that list but nothing change, not even the URL with the professor.php?anoSemestre=xx.
Also, when I try to use the $_GET['anoSemestre'] the page doesnt show any change or any ECHO.
But If I go to Chrome spector>NEtwork and click the ajax I just made, it shows me the page with the data I sent.
Cant find out what I'm doing wrong.
UPDATE
I did what was suggested me, now I'm working with the data I get from the success callback:
<script type="text/javascript">
$('#selectSemestres').change(function(obj){
var anoSemestre = $(this).val();
$.ajax({
type: 'GET',
url: '{{ route('professor') }}',
data: {anoSemestre: anoSemestre},
success: function(data){
var lista = $(data).find('#list-professores'); //Get only the new professor list and thier disciplines
$('#list-professores').remove(); //Remove old list
$('#professores').append(lista); //Append the new list where the old list was before.
}
});
})
</script>
The return of var lista = $(data).find('#list-professores'); is:
Accordion Effect
#list-professores li input[name='item']:checked ~ .prof-disciplinas {
height: auto;
display:block;
min-height:40px;
max-height:400px;
}
This list is an Accordion Menu (using a checkbox and changing it with js&css), so everytime I click on a professor < li>, it's suppose to open and show a sublist (disciplines of that professor I clicked). But it's not opening anymore and no errors on the console. No idea why.
The issue here is what you are returning in your controller and how you do it, you don´t need to redirect or refresh the entire page. This could be achived using a single blade partial for the piece of code you may want/need to update over ajax. Assuming you have an exlusive view for that info, you could solve this with something like this:
in your view:
<div class="tableInfo">
<!--Here goes all data you may want to refresh/rebuild-->
</div>
In your javascript:
<script type="text/javascript">
$('#selectSemestres').change(function(obj){
var anoSemestre = $(this).val();
$.ajax({
type: 'GET',
url: '{{ route('professor') }}',
data: {anoSemestre: anoSemestre},
success: function(){
$('.tableInfo').html(data); //---------> look at here!
}
});
})
</script>
in your controller:
public function getProfessorList()
{
$professor = Professor::all();
$ano_semestre = isset($_GET['anoSemestre']) ? $_GET['anoSemestre'] : Horario::first()->distinct()->pluck('ano_semestre');
$semestres = Horario::distinct()->select('ano_semestre')->get()->toArray();
if (Request::ajax()) {
return response()->json(view('YourExclusiveDataPartialViewHere', ['with' => $SomeDataHereIfNeeded])->render()); //---------> This is the single partial which contains the updated info!
}else{
return View::make('professor', compact('professor', 'semestres', 'ano_semestre'));//---------> This view should include the partial for the initial state! (first load of the page);
}
}

How to change url dropzone? URL dynamically with ajax success

I read this: https://github.com/enyo/dropzone/wiki/Set-URL-dynamically but i dont got success... :(
I have 1 form...
And i send the inputs with ajax.
The ajax returns the new id of user. in this moment i want to change de url dropzone for to set path to id of the new user.
$.ajax({
type: "POST",
url: "class/inserir.php?funcao=teste",
data: formdata,
dataType: "json",
success: function(json){
if(json.sucesso=="sim"){
alert("Wait! Sending Pictures.");
this.options.url = "class/upload_img.php?"+json.id;
myDropzone.processQueue();
}else{
location.href="home.php?ir=cad_animal&cad=nao&erro="+json.erro;
}
}
});
var myDropzone = new Dropzone("#imagens", {
url: "class/upload_imgteste.php",
paramName: "file", // The name that will be used to transfer the file
maxFilesize: 1, // MB
addRemoveLinks : true,
dictResponseError: "Não foi possível enviar o arquivo!",
autoProcessQueue: false,
thumbnailWidth: 138,
thumbnailHeight: 120,
});
sorry for my bad english!
Thanks for all.
You may add a function on dropzone's "processing" event listener.
Dropzone.options.myDropzone = {
init: function() {
this.on("processing", function(file) {
this.options.url = "/some-other-url";
});
}
};
Here is the link where I got the code and it works for me: https://github.com/enyo/dropzone/wiki/Set-URL-dynamically
change this
this.options.url = "class/upload_img.php?"+json.id;
to this
myDropzone.options.url = "class/upload_img.php?"+json.id;
Does that work?
New answer for an old question only because I found this answer and the link to the dropzone wiki and didn't like it. Modifying the options of the plugin multiple times like that seems very wrong.
When dropzone uses some options it runs it through a resolveOption function passing in a files array. In the current branch you can define a function for the options: method, url and timeout.
Here's a complete working example including delaying for the ajax:
Dropzone.autoDiscover = false;
const doStuffAsync = (file, done) => {
fetch('https://httpbin.org/get').then((response) => {
file.dynamicUploadUrl = `https://This-URL-will-be-different-for-every-file${Math.random()}`
done();//call the dropzone done
})
}
const getMeSomeUrl = (files) => {
return `${files[0].dynamicUploadUrl}?sugar&spice`;
}
let myDropzone = new Dropzone("#my-awesome-dropzone", {
method: "put",
accept: doStuffAsync,
url: getMeSomeUrl
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.4.0/min/dropzone.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.4.0/min/dropzone.min.css">
<form action="/file-upload" class="dropzone" id="my-awesome-dropzone">
</form>
If you need to change the URL dropzone posts to dynamically for each file, you can use the processingfile event and change the options.url.
<form id="my-dropzone" action="/some-url" class="dropzone"></form>
<script>
Dropzone.options.myDropzone = {
init: function() {
this.on("processing", function(file) {
this.options.url = "/some-other-url";
});
}
};
</script>
Another way that worked for me (accept event callback):
$('div#dropzone').dropzone({
options...,
accept: function (file, done) {
this.options.url = 'the url you want';
}
});
BlueWater86's answer didn't work for me. But I agree that changing myDropzone.options.url each time is bad practice, and it actually doesn't work if you are dragging a lot of files into the uploader at the same time.
I wrote the following code and it works well for uploading one file at time and for many at a time. I'm using Backblaze B2 but it should also work for S3.
myDropzone.on('addedfile', function(file) {
options = {
filename: file.name,
type: file.type,
_: Date.now()
};
// Make the request for the presigned Backblaze B2 information, then attach it
$.ajax({
url: '/presign_b2',
data: options,
type: 'GET',
success: function(response){
file.dynamicUrl = response['url'];
myDropzone.enqueueFile(file);
}
});
});
myDropzone.on('sending', function(file, xhr) {
xhr.open("PUT", file.dynamicUrl); // update the URL of the request here
var _send = xhr.send;
xhr.send = function() {
_send.call(xhr, file);
}
});

Updating a dropdown via knockout and ajax

I am trying to update a dropdown using knockout and data retrieved via an ajax call. The ajax call is triggered by clicking on a refresh link.
The dropdown is successfully populated when the page is first rendered. However, clicking refresh results in clearing the dropdown instead of repopulating with new data.
Html:
<select data-bind="options: pages, optionsText: 'Name', optionsCaption: 'Select a page...'"></select>
<a id="refreshpage">Refresh</a>
Script:
var initialData = "[{"Id":"231271443653720","Name":"Car2"},{"Id":"439319486078105","Name":"Electronics1.2"},{"Id":"115147185289433","Name":"Product"},{"Id":"145033098963549","Name":"Product2"}]";
var viewModel = {
pages : ko.mapping.fromJS(initialData)
};
ko.applyBindings(viewModel);
$('#refreshpage').click(function() {
$.ajax({
url: "#Url.Action("GetPageList", "FbWizard")",
type: "GET",
dataType: "json",
contentType: "application/json charset=utf-8",
processData: false,
success: function(data) {
if (data.Success) {
ko.mapping.updateFromJS(data.Data);
} else {
displayErrors(form, data.Errors);
}
}
});
});
Data from ajax call:
{
"Success": true,
"Data": "[{"Id":"231271443653720","Name":"Car2"},{"Id":"439319486078105","Name":"Electronics1.2"},{"Id":"115147185289433","Name":"Product"},{"Id":"145033098963549","Name":"Product2"}]"
}
What am I doing wrong?
The problem you have is that you are not telling the mapping plugin what to target. How is it suppose to know that the data you are passing is supposed to be mapped to the pages collection.
Here is a simplified version of your code that tells the mapping what target.
BTW The initialData and ajax result were the same so you wouldn't have noticed a change if it had worked.
http://jsfiddle.net/madcapnmckay/gkLgZ/
var initialData = [{"Id":"231271443653720","Name":"Car2"},{"Id":"439319486078105","Name":"Electronics1.2"},{"Id":"115147185289433","Name":"Product"},{"Id":"145033098963549","Name":"Product2"}];
var json = [{"Id":"231271443653720","Name":"Car2"},{"Id":"439319486078105","Name":"Electronics1.2"},{"Id":"115147185289433","Name":"Product"}];
var viewModel = function() {
var self = this;
this.pages = ko.mapping.fromJS(initialData);
this.refresh = function () {
ko.mapping.fromJS(json, self.pages);
};
};
ko.applyBindings(new viewModel());
I removed the jquery click binding. Is there any reason you need to use a jquery click bind instead of a Knockout binding? It's not recommended to mix the two if possible, it dilutes the separation of concerns that KO is so good at enforcing.
Hope this helps.

Resources