Using document.currentScript to append data to divs - javascript

I want to append data into divs by passing their id as attributes in a script tag. In this example the first-div should get get 'test1' appended to it, and the second-div should get the 'test2' appended to it.
However, the result it that both 'test1' and 'test2' are appended to second-div. first-div is empty. I'm guessing it has to do with how document.currentScript is functioning. Is there any way to get the result I am looking for?
<div id="first-div"></div>
<div id="second-div"></div>
<script attr1="name1" attr2="name2" to-div="first-div" type="text/javascript">
var this_script = document.currentScript;
var attr1 = this_script.getAttribute('attr1');
var attr2 = this_script.getAttribute('attr2');
var append_div = this_script.getAttribute('to-div');
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function(data) {
$('#' + append_div).append("test1");
});
</script>
<script attr1="name3" attr2="name4" to-div="second-div" type="text/javascript">
var this_script = document.currentScript;
var attr1 = this_script.getAttribute('attr1');
var attr2 = this_script.getAttribute('attr2');
var append_div = this_script.getAttribute('to-div');
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function(data) {
$('#' + append_div).append("test2");
});
</script>
Also, in the solution, the scripts cannot have id attributes, which is why I am trying to use document.currentScript.
The reason for this is that the code will be hosted on my servers. The code will append information into the divs the user wants, given parameters passed through attributes on the script tag. In the end the user should be able to use:
<script attr1="var1" attr2="var2" to-div="custom-div" src="http://www.myurl.com/assets/script.js" type="text/javascript"></script>
To insert data into their custom-div based on code I run on my servers dependend on the parameters attr1 and attr2 they provide.

Your problem is that var append_div is a global variable and each time a new script tag is encountered it gets overwritten with the new value.
Since ajax is asynchronous , by the time the responses return the other script tags will have been evaluated so append_div will have the value of the last script tag.
You could fix this by creating a function that wraps the ajax
function doAjax(elementId, attr1) {
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function (data) {
$('#' + elementId).append("test2");
}
});
}
doAjax(append_div, attr1);
An even better solution as pointed out by #Rhumborl is to use an IIFE
(function( elementId, attr1){
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function (data) {
$('#' + elementId).append("test2");
}
});
}(elementId, attr1);
Or wrap all of your code in an IIFE and no arguments would need to be passed in.
(function(){
var this_script = document.currentScript;
var attr1 = this_script.getAttribute('attr1');
var attr2 = this_script.getAttribute('attr2');
var append_div = this_script.getAttribute('to-div');
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function(data) {
$('#' + append_div).append("test2");
}
});
}();

Related

How get a variable from HTML in JavaScript/Ajax Call

I'm using Zend Framework 2.
I would like to know how to get data defined in html in my javascript code.
html
<tr class="MyClass" data-MyData="<?php echo json_encode($array);?>">
javascript
$(document).on('click','.MyClass', function () {
var temp =document.getElementsByClassName("data-MyData");
$.ajax({
url: path_server + "pathDefinedInMyConfig",
type: 'post',
encode: true,
dataType: 'json',
data: {
'temp ': temp
},
success: function (data) {
//some code
},
error: function () {
alert("ERROR");
}
});
});
The problem is I don't have access to row in my Controller method. And i want to have access to My $array defined in html in my Controller.
Problem is that you are trying to find a class by the name data-MyData, but the object you "want" to look for is "MyClass"
Try something like var temp =document.getElementsByClassName("MyClass").attr("data-MyData");
Even better is that since you click on the object with MyClass you can use $(this).attr('data-MyData');
then result will look like: var temp = $(this).attr('data-MyData');
Simply replace temp var assignment line:
var temp =document.getElementsByClassName("data-MyData");
with this one:
var temp = this.getAttribute("data-MyData");
Since you use jQuery use the following:
$('.MyClass').data('MyData')
or
$('.MyClass').attr('data-MyData')
use like this-
$(document).on('click','.MyClass', function () {
var temp =$(this).attr('data-MyData');
$.ajax({
url: path_server + "pathDefinedInMyConfig",
type: 'post',
encode: true,
dataType: 'json',
data: {
'temp ': temp
},
success: function (data) {
//some code
},
error: function () {
alert("ERROR");
}
});});
You have a wrong selector. document.getElementsByClassNames() returns the collections so you have to loop through to get the target element:
var temp =document.getElementsByClassName('MyClass');
[].forEach.call(temp, function(el){
console.log(el.dataset['MyData']);
});
or as you are using jQuery then you can use .data():
var temp =$(this).data("MyData");
and with javascript:
var temp =this.dataset["MyData"];
// var temp =this.dataset.MyData; // <---this way too.

Ajax Response add under each element

I have a question that I can't seem to answer about Jquery Ajax Response.
I use a for each to select some data from <p> tags in each info_div. This data I then use to do a ajax call to a service that replies with a XML. I want to place some elements from this XML under each div from where I took the two variables. Each div should have it's own reply.
$(document).ready(function () {
$('#action-button').click(function () {
$(".info_div").each(function () {
var var1 = $(this).find('p:nth-child(4)').text();
var1 = var1.slice(-10);
var var2 = $(this).find('p:nth-child(8)').text();
var2 = var2.slice(-1);
$.ajax({
type: "GET",
url: "http://www.mypage.com/mypage&value1=" + "va1" + "&value2=" + "var2",
cache: false,
dataType: "xml",
success: function (xml) {
$(xml).find('member').each(function () {
var name = $(this).find("title").text()
/* how do I get this variable under each $('.info_div') from where I selected the var1 and var2
Every attempt I made places all replies under all the divs in class .info_div */
});
}
});
});
});
});
I would not recommend you to send ajax requests in a loop. Better collect all your data, then send it to the server and handle the response.
Meanwhile, if you insist to do it in a loop, you should make a reference to the iterated element from $(".indo_div) collection, and use it in ajax callback.
$(".info_div").each(function() {
var _that = $(this);
var var1 = $(this).find('p:nth-child(4)').text();
var1 = var1.slice(-10);
var var2 = $(this).find('p:nth-child(8)').text();
var2 = var2.slice(-1);
$.ajax({
type: "GET",
url: "http://www.mypage.com/mypage&value1=" + "va1" + "&value2=" + "var2",
cache: false,
dataType: "xml",
success: function(xml) {
$(xml).find('member').each(function(){
var name = $(this).find("title").text()
that.append(name);
});
}
});
});

Getting this in ajax result

im trying to make a script that changes P lines to input fields, let user edit them and then revert back to p lines after a check in an external php document through ajax. However the problem seems to be that I cant use this within the ajax part, it breaks the code. How can I solve that? Do I need to post the HTML?
$(document).ready(function () {
function changeshit(result, that) {
if (result == "success") {
$(that).closest('div').find('input').each(function () {
var el_naam = $(that).attr("name");
var el_id = $(that).attr("id");
var el_content = $(that).attr("value");
$(that).replaceWith("<p name='" + el_naam + "' id='" + el_id + "'>" + el_content + "</p>");
});
$(".editlink").replaceWith("Bewerken");
} else {
alert(result);
}
}
$(".editinv").on('click', 'a', function () {
var editid = $(this).attr("id");
var edit_or_text = $(this).attr("name");
if (edit_or_text == "edit") {
$(this).closest('div').find('p').each(function () {
var el_naam = $(this).attr("name");
var el_id = $(this).attr("id");
var el_content = $(this).text();
$(this).replaceWith("<input type='text' name='" + el_naam + "' id='" + el_id + "' value='" + el_content + "' />");
});
$(".editlink").replaceWith("Klaar");
} else if (edit_or_text == "done") {
var poststring = "";
$(this).closest('div').find('input').each(function () {
var el_naam = $(this).attr("name");
var el_id = $(this).attr("id");
var el_content = $(this).attr("value");
poststring = poststring + '' + el_naam + '=' + el_content + '&';
});
poststring = poststring + 'end=end'
$.ajax({
url: 'http://' + document.domain + '/klanten/updateaddress.php',
type: 'post',
data: poststring,
success: function (result, this) {
changeshit(result, this);
}
});
}
});
});
Yes, the common solutions is declare a var example self = this and use that variable
var self = this;
$.ajax({
url: 'http://'+document.domain+'/klanten/updateaddress.php',
type: 'post',
data: poststring,
success: function(result) {
changeshit(result, self);
}
});
}
In that way, the this context is save in the variable.
Try the following:
Right under $(".editinv").on('click', 'a', function () { add
$(".editinv").on('click', 'a', function () {
var element = this;
And then change this to:
$.ajax({
url: 'http://' + document.domain + '/klanten/updateaddress.php',
type: 'post',
data: poststring,
success: function (result) {
changeshit(result, element);
}
});
That is if I am understanding correctly what you are trying to do
If you simply add:
context: this
to the $.ajax options then the success handler will automatically be called with the correct value of this, so you won't need the that parameter.
You'll then also no longer need the extra function wrapper around the success callback, so you can just use:
$.ajax({
url: 'http://' + document.domain + '/klanten/updateaddress.php',
type: 'post',
data: poststring,
context: this, // propagate "this"
success: changeshit // just pass the func ref
});
There are a few ways you can achieve this
1) If you read the docs (jQuery.ajax) you'll see that you can supply a context to the ajax method
context
Type: PlainObject This object will be made the context of all Ajax-related callbacks. By default, the context is an object that
represents the ajax settings used in the call ($.ajaxSettings merged
with the settings passed to $.ajax).
$.ajax({
url: 'http://'+document.domain+'/klanten/updateaddress.php',
type: 'post',
data: poststring,
context: this,
success: function(result) {
// the context sent above would become the context of this function when called by jquery
changeshit(result, this);
}
});
Using it this way you could even do it like the bellow code
function changeshit (result) {
var $that = $(this);
if (result == "success") {
$that.closest('div')... // cool ha ?
};
$.ajax({
url: 'http://'+document.domain+'/klanten/updateaddress.php',
type: 'post',
data: poststring,
context: this,
success: changeshit
});
2) You can take advantage of closures ( read more here or search google ), so your code would become
var context = this;
$.ajax({
url: 'http://'+document.domain+'/klanten/updateaddress.php',
type: 'post',
data: poststring,
success: function(result) {
// here you can use any variable you declared before the call
changeshit(result, context);
}
});
As a side note, i would recommend you use variable/object caching, so declare var $this = $(this) at the top of the function and use it thruought your function, instead of calling $(this) each time you need it.

ajax success event doesn't work after being called

After searching here on SO and google, didn't find an answer to my problem.
The animation doesn't seem to trigger, tried a simple alert, didn't work either.
The function works as it is supposed (almost) as it does what i need to, excluding the success part.
Why isn't the success event being called?
$(function() {
$(".seguinte").click(function() {
var fnome = $('.fnome').val();
var fmorada = $('.fmorada').val();
var flocalidade = $('.flocalidade').val();
var fcodigopostal = $('.fcodigopostal').val();
var ftelemovel = $('.ftelemovel').val();
var femail = $('.femail').val();
var fnif = $('.fnif').val();
var fempresa = $('.fempresa').val();
var dataString = 'fnome='+ fnome + '&fmorada=' + fmorada + '&flocalidade=' + flocalidade + '&fcodigopostal=' + fcodigopostal + '&ftelemovel=' + ftelemovel + '&femail=' + femail + '&fnif=' + fnif + '&fempresa=' + fempresa;
$.ajax({
type: "GET",
url: "/ajaxload/editclient.php",
data: dataString,
success: function() {
$('.primeirosector').animate({ "left": "+=768px" }, "fast" );
}
});
return false;
});
});
you are trying to pass query string in data it should be json data.
Does your method edit client has all the parameters you are passing?
A simple way to test this is doing the following:
change this line to be like this
url: "/ajaxload/editclient.php" + "?" + dataString;
and remove this line
data: dataString
The correct way of doing it should be, create a javascript object and send it in the data like so:
var sendData ={
fnome: $('.fnome').val(),
fmorada: $('.fmorada').val(),
flocalidade: $('.flocalidade').val(),
fcodigopostal: $('.fcodigopostal').val(),
ftelemovel: $('.ftelemovel').val(),
femail: $('.femail').val(),
fnif: $('.fnif').val(),
fempresa: $('.fempresa').val()
}
$.ajax({
url: "/ajaxload/editclient.php",
dataType: 'json',
data: sendData,
success: function() {
$('.primeirosector').animate({ "left": "+=768px" }, "fast" );
}
});
Another thing shouldn't this be a post request?
Hope it helps

jqGrid: grid function executes only once

Sorry, this is a Javascript beginner question. My jqGrid function works fine the first time around, but when I call it a second time, nothing happens, no request is issued. Code fragment:
$(document).ready(function() {
$("#submit").click(function(e) {
e.preventDefault();
var brandsDropdown = document.getElementById("brandsDropdown");
var brandId = brandsDropdown.options[brandsDropdown.selectedIndex].value;
var searchParams = "brandId=" + brandId;
doGrid(searchParams);
});
});
function doGrid(searchParams) {
alert("doGrid, searchParams:" + searchParams);
var url="${pageContext.request.contextPath}/services/setup/project";
var editurl="${pageContext.request.contextPath}/services/setup/project";
$("#projectList").jqGrid({
url: url + "?" + searchParams,
editurl: editurl,
datatype: 'xml',
mtype: 'GET',
...
});
The alert() shows me that doGrid() is really called successfully the second time. So it's really the $("projectList").jqGrid() function that doesn't execute, or fails silently .. Unless I made an obvious mistake in the way I call it?
I think the second time is no longer a need to regenerate the entire Grid. Then you only change the set parameters and grid computing to date. For this you need a trigger("reloadGrid") call.
$(document).ready(function() {
var runonce=false;
$("#submit").click(function(e) {
e.preventDefault();
var brandsDropdown = document.getElementById("brandsDropdown");
var brandId = brandsDropdown.options[brandsDropdown.selectedIndex].value;
var searchParams = "brandId=" + brandId;
doGrid(searchParams);
});
});
function doGrid(searchParams) {
alert("doGrid, searchParams:" + searchParams);
var url="${pageContext.request.contextPath}/services/setup/project";
var editurl="${pageContext.request.contextPath}/services/setup/project";
if (false==runonce) {
$("#projectList").jqGrid({
url: url + "?" + searchParams,
editurl: editurl,
datatype: 'xml',
mtype: 'GET',
...
});
runonce=true;
} else {
$("#projectList").jqGrid({
url: url + "?" + searchParams,
editurl: editurl
}).trigger("reloadGrid");
}

Categories

Resources