Pass some instructions to a function - javascript

I'm trying to deduplicate a js code of major of form that do an ajax request, I initially do a php function that generate any form onsubmit function passing the different code as parameters but don't seems good.
After I tried to a javascript function instead, for simple variables I did it working, for example:
// <script> inside of the page generate by php (and in some cases in html received by other ajax request)
$('#f_man-marker_edit-marker').on('submit', function(e){
TM.editMarker(e, $(this), 'man-marker_edit-marker');
});
...
// in other js file
TM.editMarker = function (e, form, ajax_request) {
// stop browser from submitting form!
e.preventDefault();
// Abort any pending request
if (request) request.abort();
// Let's select and cache all the fields
let inputs = form.find("input, select, button, textarea");
// Serialize the data in the form
let serializedData = form.serialize();
// Let's disable the inputs for the duration of the Ajax request.
// Note: we disable elements AFTER the form data has been serialized.
// Disabled form elements will not be serialized.
inputs.prop("disabled", true);
request = $.ajax({
url: "ajax.php?req=" + ajax_request,
type: "post",
data: serializedData,
dataType: "html"
});
request.done(function (response) {
$("#ajaxoutput2").empty().append(response);
$("#ResultModal2").modal("show");
});
request.fail(function (jqXHR, textStatus, errorThrown) {
console.error(
"Ajax " + ajax_request + " request failed. The following error occurred: " +
textStatus, errorThrown
);
});
request.always(function () {
inputs.prop("disabled", false);
});
};
Now is missed pass request.done instructions as parameter but I not found a good and working way to do it.
Put them in a function gave me the variable response not defined, also adding it as parameter.
More exactly I tried:
$('#f_man-marker_edit-marker').on('submit', function(e){
let req_done = function (response) {
$("#ajaxoutput2").empty().append(response);
$("#ResultModal2").modal("show");
};
TM.editMarker(e, $(this), 'man-marker_edit-marker', req_done());
});
...
// in other js file
TM.editMarker = function (e, form, ajax_request, req_done()) {
...
request.done(function (response) {
req_done(response);
});
...
};
Thas is not working.
Is possible to pass the instructions as they are and have them working or must be in a function? If must be in a function what is the right way to do it? Probably is possibile with eval() but seems highly discouraged and I not tried it for now.
EDIT:
I try to explain better: what I try to do is have a php or js function to call and pass as parameters the only things that changes, for example on on hundreds of similar forms that I will do on the project it will be fine there will be thousands or tens of thousands of lines of duplicate code avoided and a possible refactor or future improvements much simpler and faster.
I started with a generation from php, for example:
...
// "f_man-marker_add-marker" is the id of the form, "man-marker_add-marker" is the id of the ajax request, $man_marker_jap1 contain that instructions printed inside of request.done function (they can be different on any form)
TM\UI\JSHelper::jqueryAjaxPost(
"f_man-marker_add-marker", "man-marker_add-marker", $man_marker_jap1);
.....
// in the file of TM\UI\JSHelper:
...
/**
* Generate a jquery ajax of type post and datatype html
* will call the url ajax.php?req=$request_name
* and request.done will do what define in $done_content
*
* #param string $form_id Id of the form
* #param string $request_name Name of the ajax request parameter
* #param string $done_content Content of request.done
*/
public static function jqueryAjaxPost(string $form_id, string $request_name, string $done_content){
echo <<<HTML
$("#$form_id").submit(function(event){
// Prevent default posting of form - put here to work in case of errors
event.preventDefault();
// Abort any pending request
if (request) { request.abort(); }
let form = $(this);
// Let's select and cache all the fields
let inputs = form.find("input, select, button, textarea");
// Serialize the data in the form
let serializedData = form.serialize();
// Let's disable the inputs for the duration of the Ajax request.
// Note: we disable elements AFTER the form data has been serialized.
// Disabled form elements will not be serialized.
inputs.prop("disabled", true);
request = $.ajax({
url: "ajax.php?req=$request_name",
type: "post",
data: serializedData,
dataType: "html"
});
request.done(function (response){
$done_content
});
request.fail(function (jqXHR, textStatus, errorThrown){
console.error(
"Ajax $request_name request failed. The following error occurred: "+
textStatus, errorThrown
);
});
request.always(function () {
inputs.prop("disabled", false);
});
});
HTML;
}
but not have js "issue" (if done correctly) because the generated code is specific per form and "full js" without call to other external functions.
I then thinked to do it mainly in js only file (which to logic would seem more correct rather generate all the js from php) and was ok except of the content of request.done that must change, so I open this post to aswer what is the best and correct way to do it.
If instead there is no better method to do what I need mainly in js and the less worst seems to remain in the php generation tell me.
EDIT2:
I did other tests and found a working solution without using eval (I don't know if good):
// inside a <script> of part of page generated by php or html code received from ajax request
$('#f_man-marker_edit-marker').on('submit', function(e){
let req_done = function (response) {
$("#ajaxoutput2").empty().append(response);
$("#ResultModal2").modal("show");
};
TM.jqueryAjaxPost(e, $(this), 'man-marker_edit-marker', req_done);
});
...
// in other js-only file
/**
* Basic jquery ajax request of type post from form
* where changes only request.done content
* #param e Event received from onsubmit of the form
* #param form Receive the element with $(this)
* #param ajax_request Name of the ajax request send to php
* #param req_done Instruction to do on request.done
*/
TM.jqueryAjaxPost = function (e, form, ajax_request, req_done) {
// stop browser from submitting form!
e.preventDefault();
// Abort any pending request
if (request) request.abort();
// Let's select and cache all the fields
let inputs = form.find("input, select, button, textarea");
// Serialize the data in the form
let serializedData = form.serialize();
// Let's disable the inputs for the duration of the Ajax request.
// Note: we disable elements AFTER the form data has been serialized.
// Disabled form elements will not be serialized.
inputs.prop("disabled", true);
request = $.ajax({
url: "ajax.php?req=" + ajax_request,
type: "post",
data: serializedData,
dataType: "html"
});
request.done(function (response) {
req_done(response);
});
request.fail(function (jqXHR, textStatus, errorThrown) {
console.error(
"Ajax " + ajax_request + " request failed. The following error occurred: " +
textStatus, errorThrown
);
});
request.always(function () {
inputs.prop("disabled", false);
});
};
Is this good or is there a better way to do it and/or possible improvement?
EDIT3:
I tried also to do something working with additional parameters:
TM.deleteMarker = function (id) {
let req_done = function (response, parArray) {
$("#ajaxoutput").empty().append(response);
$('#link_open-marker' + parArray[id]).remove();
};
TM.jqueryAjaxGet('man-marker_delete-marker&id=' + id, req_done, {id: id});
};
/**
* Basic jquery ajax request of method get and datatype html
* #param ajax_request Name of the ajax request send to php and get parameters, it will be
* will be added to the end of the url
* #param req_done Instruction to do on request.done
* #param parArray Additional parameters used in req_done
*/
TM.jqueryAjaxGet = function (ajax_request, req_done, parArray = {}) {
// Abort any pending request
if (request) {
request.abort();
}
request = $.ajax({
url: "ajax.php?req=" + ajax_request,
method: "get",
dataType: "html"
});
request.done(function (response) {
req_done(response, parArray);
});
request.fail(function (jqXHR, textStatus, errorThrown) {
console.error(
"Ajax " + ajax_request + " request failed. The following error occurred: " +
textStatus, errorThrown
);
});
};
don't gave errors or warning and work all except
$('#link_open-marker' + parArray[id]).remove();
so I suppose I did something wrong about parArray but I not undestand what, Can someone help me to solve (or do in a different way if not good this) please?
Thanks for any reply and sorry for my bad english.

I'm not quite sure if i understood your question right, but if its about getting a done callback outside of your method you have two possible ways of doing that.
Use closures:
TM.editMarker = function (e, form, ajax_request, doneHandler) {
...
request.done(function (response) {
$("#ajaxoutput2").empty().append(response);
$("#ResultModal2").modal("show");
if(doneHandler !== undefined)
doneHandler();
});
}
TM.editMarker(e, $(this), 'man-marker_edit-marker', function() {
console.log("done");
});
Use promises:
TM.editMarker = function (e, form, ajax_request) {
...
var prom= jQuery.Deferred();
request.done(function (response) {
$("#ajaxoutput2").empty().append(response);
$("#ResultModal2").modal("show");
prom.resolve();
});
return prom.promise();
}
TM.editMarker(e, $(this), 'man-marker_edit-marker').then(function() {
console.log("done");
});
Answer on edit:
Ok, so what you are trying to do is executing a javascript function through the ajax response. You could achieve this by doing something like this:
$.ajax({
url: "somejs.js",
context: document.body,
success: function(responseText) {
eval(responseText);
}
});
However this is really dirty and not good practice because javascript is usually UI manipulating commands. Keep the UI stuff in the frontend and only return raw data / json from your backend. Can you give me an example of what the response looks like then I can give you an example of how I would solve it.

Related

Jsonresult is failing with parameter in my Ajax Call. Why is it happening?

That's my script on my view.
$(function () {
$('#buttonx').on("click", function (e) {
e.preventDefault();
$.ajax({
url: 'Ficha/VerificarPatrocinador',
contentType: 'application/json; charset=utf-8',
type: 'GET',
dataType: 'json',
data: {i: 100036},
success: function (data) {
$(data).each(function (index, item) {
//$('#NomePatr').append(item.Nome)
$("#NomePatr").val(item.Nome);
});
}
});
});
});
</script>
That's my action on my controller.
public JsonResult VerificarPatrocinador(int i)
{
var db = new FMDBEntities();
db.Configuration.ProxyCreationEnabled = false;
db.Configuration.LazyLoadingEnabled = false;
var consulta = db.Tabela_Participante.Where(p => p.ID_Participante == i);
return Json(consulta.
Select(x => new
{
Nome = x.Nome
}).ToList(), JsonRequestBehavior.AllowGet);
}
I'm a newbie in Ajax/Jquery, when I exclude the parameter it is ok, however, when I try to put the data: {i: 100036} in my script and the parameter in my action. It doesn't work. Why is it happening?
The controller is going fine. The parameter even passes, but I can't return this result in my View.
Thank you.
use [HttpPost] attribute on your controller method
[HttpPost]
public JsonResult VerificarPatrocinador(int i)
{
//Write Your Code
}
and change the ajax type attribute from "GET" to "POST" and use JSON.stringify. Also check the url carefully. your ajax should look like this
$(function () {
$('#buttonx').on("click", function (e) {
e.preventDefault();
$.ajax({
url: 'Ficha/VerificarPatrocinador',
contentType: 'application/json; charset=utf-8',
type: 'POST',
dataType: 'json',
data: JSON.stringify({i: 100036}),
success: function (data) {
$(data).each(function (index, item) {
//$('#NomePatr').append(item.Nome)
$("#NomePatr").val(item.Nome);
});
}
});
});
});
Hope it will help you
I think that #StephenMuecke may be on to something, because I was able to reproduce the (intended) logic with a new project.
The first thing to determine is where the code is going wrong: the server or the client.
Try using the Visual Studio debugger, and placing a breakpoint in VerificarPatrocinador. Then run the client code to see if the breakpoint is hit. When this succeeds, this means the problem is on the client end.
From there use the web browser's debugger in order to determine what is happening. Use the .fail function on the return result from .ajax in order to determine if there was a failure in the HTTP call. Here is some sample code that you can use to analyze the failure:
.fail(function (jqXHR, textStatus, errorThrown) {
alert(textStatus);
});
For more information check out http://api.jquery.com/jquery.ajax/
Change following code when ajax success
$.each(data, function (index, item) {
$("#NomePatr").val(item.Nome);
});
because when you are getting data as object of array, array or collection you can iterate using this syntax and then you can pass to var,dom...and so on where you want to display or take.
jQuery.each() means $(selector).each() you can use for dom element like below syntax: for example
<ul>
<li>foo</li>
<li>bar</li>
</ul>
<script>
$("li").each(function( index ) {
console.log( index + ": " + $( this ).text() );
});
</script>
Using GET is working fine but if it is not secure because data is visible to user when it submit as query string.
while post have
Key points about data submitted using HttpPost
POST - Submits data to be processed to a specified resource
A Submit button will always initiate an HttpPost request.
Data is submitted in http request body.
Data is not visible in the url.
It is more secured but slower as compared to GET.
It use heap method for passing form variable
It can post unlimited form variables.
It is advisable for sending critical data which should not visible to users
so I hope you understand and change ajax type:'GET' to 'POST' if you want.
$.each() and $(selector).each()
Change this line
url: 'Ficha/VerificarPatrocinador'
to:
url: '/Ficha/VerificarPatrocinador'
Because when you use this url "Ficha/VerificarPatrocinador", it will call the API from url: current url + Ficha/VerificarPatrocinador,so it isn't correct url.

Why won't my javascript function called after ajax.success?

Why won't my function work after ajax has succeed?
I have a custom function named filter(), defined in the header as javascript file.
Then i have a series of jquery code to dynamically retrieve data from the server to populate the select box. I would like to call the filter() after the AJAX request has completed since the filter() will manage populated the select box's option.
$.ajax({
url: "checkersc2.php", //This is the page where you will handle your SQL insert
type: "GET",
data: values, //The data your sending to some-page.php
success: function (response) {
$('#loading-image').css('display', 'none');
$dropdownCondition.html(response);
filter();
},
error: function () {
console.log("AJAX request was a failure");
}
});
EDIT: my filter() code is a little long, # http://jsfiddle.net/tongky20/re5unf7p/11/
It looks like you have an invalid selector for dropdownCondition. It probably fails on that line and never calls filter. Unless you defined that variable else where try updating it to a valid element selector and see if it calls filter. Something like:
$('#dropdownCondition').html(response);
Assuming the element id is dropdownCondition.
Full function:
$.ajax({
url: "checkersc2.php", //This is the page where you will handle your SQL insert
type: "GET",
data: values, //The data your sending to some-page.php
success: function (response) {
$('#loading-image').css('display', 'none');
$('#dropdownCondition').html(response);
filter();
},
error: function () {
console.log("AJAX request was a failure");
}
});

Update db via json

I am using the following code to edit records in a database. It works great for doing an edit. I need to expand the functionality to include the ability to add or delete functions also.
On my form I use three separate buttons to select whether to Add, Edit, or Delete.
How can I expand the script to determine which of the buttons was clicked?
// Action to run on submit to add/edit/delete record from database
var request; // variable to hold request
// bind to the submit event of our form
$("#form_edit").submit(function(event){
// abort any pending request
if (request) {
request.abort();
}
// setup local variables
var $form = $(this);
// select and cache all the fields
var $inputs = $form.find("input, select, textarea");
// serialize the data in the form
var serializedData = $form.serialize();
// disable the inputs for the duration of the ajax request
$inputs.prop("disabled", true);
// define constants to be passed as parameters
var updateType = "edt"; // This needs to be changed to 'add' or 'del'
var tableName = "phasecodes";
var indexName = "phase_ID";
var recNumber = phase_ID.value;
// Build string for query input
var type = "?type=" + updateType;
var table = "&table=" + tableName;
var index = "&index=" + indexName;
var rec = "&rec=" + recNumber;
var getS = type + table + index + rec;
// execute request to update database
request = $.ajax({
url: "files_json/update_Record.php" + getS,
type: "post",
data: serializedData
});
// callback handler called on success
request.done(function (response, textStatus, jqXHR) {
console.log("Data record updated!"); // log success message to the console
});
// callback handler called on failure
request.fail(function (jqXHR, textStatus, errorThrown) {
console.error( "The following error occured: " + textStatus, errorThrown ); // log the error to the console
});
// callback handler called regardless if the request failed or succeeded
request.always(function () {
$inputs.prop("disabled", false); // reenable the inputs
});
// prevent default posting of form
event.preventDefault();
}); // End of submit function
Assuming that the three buttons within the form are of type 'submit...'
You can see this post
Something like this should return the value of the clicked button:
var val = $("input[type=submit][clicked=true]").val();

Cannot pass data with jquery ajax to php through post

I use this code, which was taken by another post of stackoverflow, but one part was not working for me.
<script>
// variable to hold request
var request;
// bind to the submit event of our form
$("#notification").submit(function(event){
// prevent default posting of form
event.preventDefault();
// abort any pending request
if (request) {
request.abort();
}
// let's select and cache all the fields
var $inputs = $form.find("input, select, button, textarea");
// let's disable the inputs for the duration of the ajax request
$inputs.prop("disabled", true);
//this code was added by me cause i saw that when i pass as data {notTitle:"smth"}
//it works, so i wanted to remake that structure and include all my elements.
// Apparently it does not work, maybe because i create a string and by
//{notTitle:"smth"}, notTitle is not passed as string.
x=$("form").serializeArray();
var str="{";
var size = x.length;
$.each(x, function(i, field){
if (field.value!="")
str = str.concat(field.name + ":" + field.value);
else
str = str.concat(field.name + ":" + "k");
if(i!=size-1)
str=str.concat(",");
});
str=str.concat("}");
// fire off the request to /form.php
request = $.ajax({
url: "test.php",
type: "POST",
dataType: 'json',
data: str//{notTitle:"s",notType:''}
});
// callback handler that will be called on success
request.done(function (response, textStatus, jqXHR){
alert(response.status);
});
// callback handler that will be called on failure
request.fail(function (jqXHR, textStatus, errorThrown){
// log the error to the console
alert(
"The following error occured: "+
textStatus, errorThrown
);
});
// callback handler that will be called regardless
// if the request failed or succeeded
request.always(function () {
// reenable the inputs
$inputs.prop("disabled", false);
});
});
</script>
And here is my php
<?php $result = array("status" => "1", "a" => "2");
$notificationTitle = htmlspecialchars($_POST["notTitle"],ENT_QUOTES,'ISO-8859-1');
echo json_encode($result); ?>
Before you suggest the use of serializing the form, I tried it and it does not work. What I noticed is that when I try to pass data to my php file, I cannot read them through $_POST['name of element']. So if I comment the second line of the php file and pass as data {notTitle:'s'} it works and I see the successful message.

JQuery Ajax Request returns no data

I am trying out JQuery Ajax methods. I wrote a simple Ajax request to fetch certain 'tagged' photos from Flickr. Following is the snippet I am using:
function startSearch() {
$(function() {
var tagValue = $("#tagInput").attr("value");
alert(tagValue);
$.ajax({
url: "http://api.flickr.com/services/feeds/photos_public.gne?tags=" + tagValue + "&tagmode=any&format=json&jsoncallback",
dataType: 'json',
async: false,
success: function(data) {
alert("Success");
$.each(data.items, function(i, item) {
var pic = item.media.m;
$("<img/>").attr("src", pic).appendTo("#images");
});
},
error: function(data, error) {
alert("Error " + error);
}
}); });
'startSearch' is associated with a Search button. User is supposed to input a 'tag' to search and on click this function gets called.
Problem is that I am not receiving any 'data' in response. Hence no images gets displayed.
What am I doing wrong here?
Thanks & Regards,
Keya
I think the problem is that you're trying to make a cross-site request, which doesn't work because of security concern. You could use JSONP instead, e.g. as described in http://www.viget.com/inspire/pulling-your-flickr-feed-with-jquery/
You can also try searching for "cross site ajax" on this site, there's plenty of discussion about it.

Categories