Call function with argument from dynamically create link - javascript

I'm trying to create a grid of divs based on JSON that is returned from my server. When I iterate the objects, I create it like this
getApps(function(data){
var displayMode = "<? echo $_GET['displayMode']; ?>";
var appsDisplayedCounter = 0;
for (var i = 0; i < data.length; i++)
{
var app = data[i];
// check if we're interested in this app
var shouldDisplay = (displayMode == 'hired' && app.hired == 1) || (displayMode == 'self' && app.hired == 0) || !displayMode;
if (shouldDisplay)
{
var innerContent;
var content = '<div class="AppContainer">';
if (appsDisplayedCounter % 2 == 0)
{
innerContent = '<img class="SquareImage" src="'+app.imagePath+'"/>\
<div class="AppContainerName AppContainerBottomSegment">'+app.name+'</div>';
}
else
{
innerContent = '<div class="AppContainerName">'+app.name+'</div>\
<img class="SquareImage AppContainerBottomSegment" src="'+app.imagePath+'"/>';
}
content = content + innerContent + '</div>';
// nest the content in a link
content = '' + content + '';
$(".MainContentContainer").append(content);
// link handler
//$('#'+app.name).click(function(){showDetailView(app.name); return false});
// increment counter
appsDisplayedCounter++;
}
}
});
function showDetailView(app)
{
alert(app);
}
function getApps(completion)
{
$.ajax({
url: '/Apps.php',
success: function(data)
{
var appsJson = data['apps'];
completion(appsJson);
},
async: false
});
}
My issue is passing the app object into my function. Clicking the div does nothing.
-- EDIT --
When I inspect the tag after it was created, it looks like this
<a id="AppName" href="javascript:showDetailView([object Object])">
I set a breakpoint in showDetailView(app) which is never called when I click this link.

You are getting [object Object] because you are referencing it as a string, but it's not a string.
If you are trying to pass the entire object into the function, then you should use JSON.Stringify()
content = '<a href="javascript:showDetailView('+ JSON.stringify(app) +')"
id="'+app.name+'">' + content + '</a>';
Then in your showDetailView function:
function showDetailView(app) {
var appJSON = JSON.parse(app);
alert(aJSON.name);
}
References
JSON Object Overview
JSON.stringify()
JSON.parse()

Related

Delete element from array when deleting record from localStorage

I have a localStorage object like this:
Key: jpxun
Value: [{"id":"0","name":"royal"},{"id":"1","name":"tippins"},{"id":"4","name":"leviosa"},{"id":"5","name":"vicious"}]
I have this JS to display output the localStorage:
var jpxun = JSON.parse(localStorage.getItem('jpxun')) || [];
if (jpxun) {
var jpxun_length = jpxun.length;
} else {
var jpxun_length = 0;
}
var hst = document.getElementById("usernames");
var MyUsernames = JSON.parse(localStorage.getItem("jpxun"));
if (jpxun_length > 0) {
// declare array to hold items for outputting later in plain text format
var plain_text_array = [];
for (var i = 0; i < MyUsernames.length; i++) {
var un1 = MyUsernames[i].name;
hst.innerHTML += "<li>" +"<a id="+MyUsernames[i].id + " href='#content' onclick='deleteById(this)'>x </a>" + un1 + "</li>";
// add word to plain text array
plain_text_array.push(un1);
}
}
Each element is outputted in a list item with an 'x' as a hyperlink so that it can be clicked and that element is deleted from localStorage.
This is the code to delete the item from localStorage:
var deleteById = function ( self ){
MyUsernames = MyUsernames.filter(function(elem) {
return elem.id !== self.id;
});
localStorage.setItem("jpxun",JSON.stringify(MyUsernames));
self.parentNode.parentNode.removeChild(self.parentNode);
}
That works fine.
Unfortunately I don't really understand how the code works in deleteById.
As that is the case, I am stuck on working out how to delete the corresponding record from plain_text_array when its value is deleted from localStorage.
I would try to find the text in the array thats includes that string 'id="item_id"':
plain_text_array = plain_text_array.filter(item => !item.includes(`id="${self.id}"`));
Just add it in the end of deleteById function.

Get .length of NEW dynamically added div

6 items are added onload using ajax. Each click, 6 items are being appended.
I want to hide #load-more button if newly added items are less than 6.
How to find the count of newly added items?
I use .length but all items are being counted.
Thanks for your help.
var max = 6;
var NewItems = $(".items").length;
if (NewItems > max) {
$("#load-more").hide();
} else {
$("#load-more").show();
}
var max = 6;
var start = 1;
var winloc = window.location;
$(window).bind('hashchange', function() {
if (winloc.hash === "" || winloc.hash === "#home") {
homeurl = `https://mailliw88.blogspot.com/feeds/posts/default?start-index=${start}&max-results=${max}&alt=json-in-script`;
loadList(homeurl);
}
}).trigger('hashchange')
function more() {
start += max;
loadList(`https://mailliw88.blogspot.com/feeds/posts/default?start-index=${start}&max-results=${max}&alt=json-in-script`);
}
function loadList(url) {
$.ajax({
url: url,
type: 'get',
dataType: "jsonp",
success: function(data) {
if (data.feed.entry) {
datas = data.feed.entry;
var entry = data.feed.entry;
for (var i = 0; i < entry.length; i++) {
postTitle = entry[i].title.$t;
items = '<div class="items"><h2>' + postTitle + '</h2></div>';
document.getElementById('showlists').innerHTML += items;
}
}
var newItems = $(".items").length;
if (newItems > max) {
$("#load-more").hide();
} else {
$("#load-more").show();
}
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='showlists'></div>
<div id='load-more' onclick="more()">
load more
</div>
Change:
var newItems = $(".items").length;
if (newItems > max) {
To:
if (data.feed.entry.length < 6)
The variable "max" will be out of scope for your "success" method since it's defined outside of it and is an integer type, so you will need to either directly add it, or use an object, like:
var max = {entries: 6};
...
if (data.feed.entry.length < max.entries)
You could add data attributes to the new items with an incrementing id so the final html would look like
<div data-load="1"></div>
<div data-load="1"></div>
...
<div data-load="2"></div>
...
and then in you're js
$(`div[data-load="${Math.max(...$('div').map(item => parseInt(item.attr("data-load"))))}"`)
would get all the latest ajax elements

It does not work "onclick" with attr () from JQuery

I'm trying to add an "onclick" event with their respective function from js JQuery to an interactive table td I'm doing in another .php file, the problem is not executed in the place where I want to do it but if the same instruction is executed correctly within an AJAX request a few lines below, will show you the code:
This instruction is giving me the problem:
$(td).attr("onclick","agregar_pensum_etapa2 (this,'"+subject+"','"+level+"','"+stage+"');");
And this, the function I want to run with the "onclick"
function agregar_pensum_etapa2(td,subject,level,stage){
$(document).ready(function(){
// Capture variables.
var id_periodo = $("#id_periodo").val();
var id_asignatura = subject;
var id_nivel = level;
var id_etapa = stage;
var id_mencion = null;
if (level> 3) {
id_mencion = 0;
}
// Modifiable column.
var tr = $(td).parent();
var index_td = $(td).index();
// First field
var valor_anterior = $(td).text();
$(td).html("<img src =" images / save_64.png 'width = '16' height = '16 '> & nbsp; & nbsp; & nbsp;' + '<input value = "' + valor_anterior + '" type = "text" style = "width: 40px; border: 1px solid #aaa;" onkeypress = "return soloNumeros (event);" maxlength = "2"> ');
$(td).removeAttr("onclick");
$(td).find("input").focus();
// Second field
var valor_anterior_cs = $(tr).find("td:eq("+(index_td+1)+")").text();
var checked_cs = "";
if (valor_anterior_cs === "X"){checked_cs = "checked"}
$ (tr) .find ("td: eq (" + (index_td + 1) + ")") html ("<input type = 'checkbox'" + checked_cs + ">").
// Third field
var valor_anterior_hum = $(tr).find("td:eq("+(index_td+2)+")").text();
var checked_hum = "";
if(valor_anterior_hum === "X") {checked_hum = "checked"}
$(tr).find("td:eq("+(index_td+2)+")").html("<input type = 'checkbox'"+checked_hum+">");
/ ************************************************* *********** /
$(td).find("img").click(function(){
var hora_asignatura = $(td).find("input").val();
var mencion_cs = "NO";
if($(tr).find("td:eq("+(index_td+1)+")").find("input").is ("checked")){mencion_cs = "YES";}
var mencion_hum = "NO";
if($(tr).find("td:eq("+(index_td+2)+")").find("input").is("checked")){mencion_hum = "YES";}
if(hora_asignatura === ""){
if(valor_anterior != ''){
$(td).html(valor_anterior);
$(tr).find("td:eq("+index_td+1)+")").text(valor_anterior_cs);
$(tr).find("td:eq("+(index_td+2)+")").text(valor_anterior_hum);
}else{
$(td).html("");
$(tr).find("td:eq("+(index_td+1)+")").text("");
$(tr).find("td:eq("+(index_td+2)+")").text("");
}
\\// --> HERE IS NOT WORKING <-- \\//
$(td).attr("onclick","agregar_pensum_etapa2(this,'"+subject +"','"+level+"','"+stage+"');");
}else if(hora_asignatura == "0"){
if(valor_anterior! = ''){
$(td).html(valor_anterior);
$(tr).find("td:eq("+(index_td+1)+")").text (valor_anterior_cs);
$(tr).find("td:eq("+(index_td+2)+")").text (valor_anterior_hum);
}else{
$(td).html("<img src =" images / diagonal.png 'height = '16' style = 'width: 15px ">");
$(tr).find("td:eq("+(index_td+1)+")").text("");
$(tr).find("td:eq("+(index_td+2)+")").text("");
}
\\// --> HERE IS NOT WORKING <-- \\//
$(td).attr("onclick","agregar_pensum_etapa2(this,'"+subject+"','"+level+ "','"+stage+"');");
}else{
$.ajax({
async: true,
cache: false,
dataType: "html"
type: 'POST'
url: "../Controlador/CtrlPensum.php"
data: {
id_periodo: id_periodo,
id_asignatura: id_asignatura,
id_nivel: id_nivel,
id_etapa: id_etapa,
hora_asignatura: hora_asignatura,
mencion_cs: mencion_cs,
mencion_hum: mencion_hum,
id_mencion: id_mencion,
record: "register"
},
success: function (response) {
//alert (response);
if($.trim(answer) === "1") {
$(td).html(hora_asignatura);
var marcar_cs_x = "";
if(mencion_cs === "SI"){marcar_cs_x = "X";}
var marcar_hum_x = "";
if(mencion_hum === "SI"){marcar_hum_x = "X";}
$(tr).find("td:eq("+(index_td+1)+")").html (marcar_cs_x).
$(tr).find("td:eq("+(index_td+2)+")").html (marcar_hum_x).
\\// --> HERE IT WORKS <-- \\//
$(td).attr("onclick", "agregar_pensum_etapa2 (this,'"+subject+"','"+level+"','"+stage+"');");
cargarTablaResumen ();
} Else {
alert ("Error SQL statement is not executed." + response);
}
//tr.fadeOut(500).fadeIn(500);
},
beforeSend: function () {}
Error: function (objXMLHttpRequest) {}
});
}
});
});
}
I try this:
$(td).click(function(){
$(td).attr("onclick","agregar_pensum_etapa2 (this,'"+subject+"','"+level+ "','"+stage+"');");
});
And in the html it prints correctly but does not work, like he was not the "onclick" there. And the function if it works, I put the onclick to that function when I load the page and if it works, but when I click the td and give back to click to restore does not restore the onclick.
Instead of setting the onclick attribute, why not do use .click() again with closures? So your code would be something like...
$(td).click(function(){
var td = this;
$(td).click(function () {
agregar_pensum_etapa2(td,subject,level,stage);
});
});
Do you write
$(Document)
Instead of $(document) with small letter "d".

JSON Object (how to not load the entire object on DOM initially)

So i am reading a local json file that consist of {[Object,Object,Object.....]}
I am using the
$.getJSON('products.json', function (pdata) {
for (var i = 0; i < pdata.data.length; i++) {
AppendtoDom(pdata.data[i]);
}
The above code reads the json objects and appends to the DOM, but i want to initially load only 100 objects at a time and on scroll keep appending.
Say there are around 1200 objects. How do i go about this?
My implementaion so far
$(function(){
loadData();
});
function loadData(){
$.getJSON('products.json', function (pdata) {
var i = 0;
function addtoDom(num){
var limit = Math.min(i + num, pdata.data.length);
for(; i < limit; i++){
getInformation(pdata.data[i]);
}
}
addtoDom(100);
$('.content').jscroll({
callback: addtoDom(100)
});
});
}
function getInformation(obj){
var content = "";
for (var i = 0; i < 4; i++) {
content += '<li>';
content += "<img src='" + obj.imageUrl + "' style='width:200px;height:200px'/>";
content += '<div class="productName">' + obj.fullName + "</div>";
content += '<div class="price">Price: ' + obj.price + "</div>";
content += '</li>';
}
$("<ul class= 'view'>" + content + "</ul>").appendTo('.content');
}
Similar question i asked in How would i implement an infinite scroll in my DOM
You can put all the objects you get back from the Ajax call into a persistent variable, add the first 100 to the DOM, keep a counter of how many you've added so far and then upon scrolling to a certain point, add another 100, add another 100 and so on.
$.getJSON('products.json', function (pdata) {
var i = 0;
function addMore(num) {
var limit = Math.min(i + num, pdata.data.length);
for (; i < limit; i++) {
AppendtoDom(pdata.data[i]);
}
}
// add the first 100
addMore(100);
// then set up whatever scroll detection you want here and
// when you decide that it has scrolled enough to add some more
// you just call addMore(100) again
});
In your specific implementation of the above idea, you have an implementation mistake. You have to pass a function reference for the callback so change this:
$('.content').jscroll({
callback: addtoDom(100)
});
to this:
$('.content').jscroll({
callback: function() {addtoDom(100);}
});
Assign your JSON to a variable and dynamically render them as needed.
var json;
$.getJSON('products.json', function (pdata) {
JSON = pdata;
};
// Scheduling logic
AppendtoDom(json[i]);

Using JavaScript to get RadGrid for print

I'm creating a print function and the key is to call the grid that I want to print. It has been working well if the grid is existing on the aspx page, until when I also need to print a list of RadGrids that are generated programmatically behind the code then JavaScript cannot detect these non-existing grids and return the error of "the control does not exist". Just to be clear, it's not working because at the time when I'm typing the code, there's no RadGrid_Dynamic on the page, hence erroring. There's nothing to do with when the page execute/page life cycle etc.
My work around is to try to call the control by string value, as using
$find('<%= RadGrid_Dynamic.ClientID %>'),
the page will highlight RadGrid_Dynamic and say it doesn't exists as mentioned above. Below is my code, I've also tried replacing the $find() with document.getElementById(), but no luck, any advice? Thanks.
function getOuterHTML(obj) {
if (typeof (obj.outerHTML) == "undefined") {
var divWrapper = document.createElement("div");
var copyOb = obj.cloneNode(true);
divWrapper.appendChild(copyOb);
return divWrapper.innerHTML
}
else {
return obj.outerHTML;
}
}
function Print() {
var previewWindow = window.open('about:blank', '', '', false);
var styleSheet = '<%= Telerik.Web.SkinRegistrar.GetWebResourceUrl(this, RadGrid1.GetType(), String.Format("Telerik.Web.UI.Skins.{0}.Grid.{0}.css", RadGrid1.Skin)) %>';
var baseStyleSheet = '<%= Telerik.Web.SkinRegistrar.GetWebResourceUrl(this, RadGrid1.GetType(), "Telerik.Web.UI.Skins.Grid.css") %>';
var htmlContent = "<html><head><link href = '" + styleSheet + "' rel='stylesheet' type='text/css'></link>";
htmlContent += "<link href = '" + baseStyleSheet + "' rel='stylesheet' type='text/css'></link></head><body>";
for (i = 1; i < 13; i++) {
var CYGrid = "RadGrid_CY_Strategy_" + String(i);
var CYradGrid = $find('<%=CYGrid.ClientID %>'); //Highlighted as red and erorr: The Name 'CYGird' does not exist in the current content
var LYGrid = "RadGrid_LY_" + String(i);
var LYradGrid = $find('<%=LYGrid.ClientID %>'); //Ditto
htmlContent += getOuterHTML(CYradGrid.get_element());
if (LYradGrid.hidden == false) {
htmlContent += getOuterHTML(LYradGrid.get_element());
}
}
htmlContent += "</body></html>";
previewWindow.document.open();
previewWindow.document.write(htmlContent);
previewWindow.document.close();
previewWindow.print();
if (!$telerik.isChrome) {
previewWindow.close();
}
}
You could programmatically assign an ID to the dynamic grid when it's being created and use that ID to do a $find().

Categories