Nestable.js issue with callback updating textarea - javascript

I'm having an issue with nestable.js and maybe I'm using the callback incorrectly. Below is my current code and I'm loading the JSON from the php variable $primary_menu_json that is passed into the function. It creates the menu with no issues and I can move my menu elements around that are created from the JSON no problem, but it's not updating my hidden textarea (#nestableOutput) on the callback.
The way I understand the callback from the documentation is it's fired when elements are reordered or nested. In my mind this would be the place to update the hidden textarea when an element is dropped. Maybe I am wrong in this thinking. Any help?
$(document).ready(function () {
function nestableJSON(jsonArray, root) {
if (typeof root === 'undefined') {
root = $('body');
}
var $div = $('<div id="nestable02a" class="dd" data-plugin="nestable"><ol class="dd-list dd3-list"></ol></div>');
root.append($div);
for(var i = 0; i < jsonArray.length; i++) {
var $li = $("<li class='dd-item dd-item-alt' id='item-" + jsonArray[i].id + "' data-id='" + jsonArray[i].id + "' data-title='" + jsonArray[i].title + "'><div class='dd-handle'></div><div class='dd-content'>" + jsonArray[i].title + "<span class='float-right wb-trash'></span></div></li>");
root.find('ol.dd-list:first').append($li);
if (typeof jsonArray[i].children !== 'undefined') {
nestableJSON(jsonArray[i].children, $li);
}
}
$('#nestable02a').nestable({
group: 1,
maxDepth: 3,
callback: function(e){
var list = e.length ? e : $(e.target);
$('#nestableOutput').text(window.JSON.stringify(list.nestable('serialize')));
console.log('json updated');
}
});
}
nestableJSON(<?php echo $primary_menu_json; ?>);
});

Related

Function within function in JavaScript - Need to understand this code:

I have below code within a function called render. How do I call the str variable value outside render function?
Also, please can you explain below code? I'm fairly new to js and head is hurting looking at the function calls having functions as a parameter.
My understanding is that app.getList is an object which takes function as a parameter? but it is not returning anything. Sorry, I'm lost here.
app.getList("FieldList", function(reply){
var str = "";
$.each(reply.qFieldList.qItems, function(index, value) {
str += value.qName + ' ';
});
console.log(str);
});
Full Code:
define(["jquery",
//mashup and extension interface
"qlik",
//add stylesheet
"text!./css/mystyle.css",
"client.utils/state",
"client.utils/routing"
],
function($, qlik, cssContent, clientState, clientRedirect) {
/*-----------------------------------------------------------------*/
// function redirect (sheetId){
// clientRedirect.goToSheet(sheetId, Object.keys(clientState.States)[clientState.state])
// }
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
var render = function($elem, layout) {
var html = '',
app = qlik.currApp();
//get list of tab objects and insert into div
app.getAppObjectList('sheet', function(arrayitem) {
//for each sheet in the app, create a list item
$.each(arrayitem.qAppObjectList.qItems, function(myindex, myvalue) {
//include the sheet id as the list item id to be used as a reference for active sheet
html += '<li id="' + myvalue.qInfo.qId + '">'; // onClick="redirect(' + value.qInfo.qId + ');
//wrap anchor tag to be used by bootstrap styling
html += '<a>';
//give the link the same name as the sheet
html += myvalue.qData.title;
html += '</a>';
html += '</li>';
});
html += '</ul></div>';
html += "<button id='myButton'> Click Me!! </button>";
console.log(arrayitem.qAppObjectList);
console.log(html);
//insert html into the extension object
return $elem.html(html);
});
/* Test Code Start from here */
app.getList("FieldList", function(reply) {
var str = "";
$.each(reply.qFieldList.qItems, function(key, value) {
str += value.qName + ' ';
});
console.log(str);
});
};
/*-----------------------------------------------------------------*/
return {
/*-----------------------------------------------------------------*/
paint: function($element, layout) {
console.count();
/*-----------------------------------------------------------------*/
$(function() {
$element.html("#myButton").click(function() {
// for(var mynum = 1; mynum <= 5; mynum++){
// alert('button test' + mynum);
// };
});
});
/*-----------------------------------------------------------------*/
render($element, layout);
/*-----------------------------------------------------------------*/
}
};
});
app.getList is probably asynchronous (meaning it runs in the background). The function you've passed to it is a callback. That function will be ran at some point in the future, once the AJAX call (or whatever asynchronous method is ran) is done.
Your callback is passed reply, which is the "return" value from getList(). You cannot access str from outside of this function. You need to do whatever code with reply and/or str in that function only.

jQuery UI accordion not working when data is refreshed

I have an HTML page in which data is being dynamically loaded into accordions. The accordion call is happening from inside a function. This function is being called at regular intervals to refresh the data. The accordion is showing correctly the first time, but getting destroyed when the data is refreshed. Here is some relevant code:
HTML:
...
<div id="itemsList"></div>
...
JavaScript:
function updateList() {
var storedStates = startSpinner(spinner, 'itemsList');
$.post('interface/getitemss.php',
function(data) {
var dataObj = $.parseJSON(data);
if(dataObj.status == 0) {
var itemDetails = dataObj['data'];
$("#itemsList").html("");
var infoLevel = getInfoLevel();
for (var i = 0; i < itemsDetails.length; i++) {
var rowContent = "<h3>";
if (item.type == 3 && item.approvals > 0) {
rowContent += "<span class='" + qaprColor + "'>";
rowContent += "<i class='icon-bell'></i>" + space + item.approvals + "</span>" + pipespace;
}
...
rowContent += "</div>";
$("#itemsList").append(rowContent);
}
$("#itemsList").accordion();
else in the code, I am using this:
var intervalTimer = setInterval(function() {updateList();}, <?php echo $interval; ?>);
This called the updateList() method regularly to update the data. The problem is, the moment this method is called, the previously-working accordion is destroyed and the data are appearing like normal HTML. Does anyone know how this could be fixed? Thanks!!
Have you tried calling destroy on the accordion before creating it again?
$("#itemsList").accordion( "destroy" );
$("#itemsList").accordion();
found in api docs

Intercept a dynamic added form submission

Normal form submission intercept can be found. But, my class is different. The form is dynamically added after calling a function. Then, the form submission cannot be captured.
How to capture the form submission like this? Better to use Jquery but altering the dynamic added form attributes is acceptable.
The following is the example.
Here is how I capture the form submission.
$(function() {
$(".formClass").submit(function(e) {
e.preventDefault();
var actionurl = e.currentTarget.action;
alert(actionurl);
});
});
Here is how forms are added after calling the function - eObj.getFormElement()
(function($){
function(eObj) {
var selector = "#abc";
//Call the function to get the form elements
eObj.getFormElement(langObj, function(err, x) {
var elem = "<ul>";
for (var i=0; i<x.length; i++) {
var formId = elementId + "_sform_" + i;
elem = elem + "<li class='product_" + i + "'>"
for (var key in x[i]) {
elem = elem + "<div class='price'>" + curMap[curKey] + x[i][key].price + "</div>";
elem = elem + "<div class='s'><form id='" + formId +"' class='formClass' method='post' action='" + x[i][key].url + "'>"
+ "<input class='s_btn' type='submit' value='" + submitLabel + "'>"
+ "</form></div>";
}
elem = elem + "</li>";
}
elem = elem + "</ul>";
//Append the form to the div after we create the forms
$(selector).append(elem);
});
}})(jQuery);
Since You can't set events for non-existing elements You need to set events for element existing.
In this case you can use document to get the event.
http://jsfiddle.net/h189o3xc/
here is a sample code.
$(document).on("submit",function(e){
if($(e.target).hasClass("formClass")){
e.preventDefault();
console.log("you can catch the event!");
//and do whatever you want.
}
});
set a event for document and whenever any submit event happens, check whether it's your target form or not. then do whatever you want if it's your target form.
EDITED
as #charlietfl mentioned,You can use extra on function's parameter instead of if statement.
the code would be something like..
$(document).on("submit",".formClass",function(e){
e.preventDefault();
console.log("you can catch the event!");
//and do whatever you want.
});
http://jsfiddle.net/h189o3xc/2/

Parsing links from an XML files with JavaScript

To display my latest blog-posts on a different page I want to parse the rss-feed from the blog and then generate elements with it.
I first tried to parse a fixed .xml file for which I wrote the following code:
var maxBlogposts = 5;
var blogPosts = 0;
$.get("rss.xml", function(data) {
$(data).find("item").each(function() {
if(blogPosts === maxBlogposts) return;
var el = $(this);
//Only display 3 posts on small devices.
var extra = (blogPosts >= 3) ? "not-small 12u(small)" : "12u(small)";
var div = $('<div class="6u ' + extra + '" class="blog-entry"></div>');
var h = $('<h4>' + el.find("title").text() + '</h4>');
var description = el.find("description").text().replace('[…]', '[…]');
var p = $('<p>' + description + '</p>');
div.append(h);
div.append(p);
$('#blog').append(div);
blogPosts++;
});
});
This worked perfectly fine. Now I want to parse the actual rss-feed. For this I wrote a PHP script which simply gets the feed and echos it.
<?php
$rss = file_get_contents('http://xn--der-grne-baum-1ob.net/feed/');
die($rss);
?>
And again I get the correct XML file on the frontend.
The problem I have is that now my code is no longer working. Getting the description was failing as well as the links. I fixed the description by accessing
el.find(description")[0].innerHTML
However I can't seem to get the links to work. The data returned from the PHP file contains a node with the link in it. The "el"-element also contains children named "link" but those no longer contain the actual link.
I feel like the links may get "escaped" during parsing? At least that is the only reason i could think of that would result in what I am observing.
The XML I am parsing comes from http://xn--der-grne-baum-1ob.net/feed/
Try
var maxBlogposts = 5
, blogPosts = 0;
$.get("https://query.yahooapis.com/v1/public/yql?q=select"
+ " * from feed where url='http://xn--der-grne-baum-1ob.net/feed/'")
.then(function(data) {
$(data.documentElement).find("results item")
.each(function() {
if(blogPosts === maxBlogposts) return;
var el = $(this);
//Only display 3 posts on small devices.
var extra = (blogPosts >= 3) ? "not-small 12u(small)" : "12u(small)";
var div = $('<div class="6u ' + extra + '" class="blog-entry"></div>');
var h = $('<h4>' + el.find("title").text() + '</h4>');
var description = el.find("description").text().replace('[…]', '[…]');
var p = $('<p>' + description + '</p>');
div.append(h);
div.append(p);
$('#blog').append(div);
blogPosts++;
});
}, function(jqxhr, textStatus, errorThrown) {
console.log(textStatus, errorThrown)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="blog"></div>
See YQL Console

how to append if found, and replace if not found at all? (xml find.each loop)

I'm trying to search a string value in an xml file, and then append to a div if the string value is found. If not found at all, then I need to display an error text in the same div that the search term was not found.
This is basically supposed to be a search page which loads the searched items into div content.
Currently my content is loading fine. The searched term if found loads all the corresponding divs from the xml, but I've been unable to display an error if the search term was not found.
My XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<items xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item>
<animal_id>1_1</animal_id>
<animal_title>Sparrow</animal_title>
<animal_generic>Birds 1</animal_generic>
<animal_category>Birds</animal_category>
<animal_code>a1</animal_code>
<animal_img>http://i.imgur.com/R0754lr.png</animal_img>
<animal_url>1_1_Animals1.html</animal_url>
</item>
<item>
<animal_id>1_2</animal_id>
<animal_title>Crow</animal_title>
<animal_generic>Birds 2</animal_generic>
<animal_category>Birds</animal_category>
<animal_code>b2</animal_code>
<animal_img>http://i.imgur.com/R0754lr.png</animal_img>
<animal_url>1_2_Animals2.html</animal_url>
</item>
<item>
<animal_id>1_3</animal_id>
<animal_title>Parrot</animal_title>
<animal_generic>Birds 3</animal_generic>
<animal_category>Birds</animal_category>
<animal_code>c3</animal_code>
<animal_img>http://i.imgur.com/R0754lr.png</animal_img>
<animal_url>1_3_Animals3.html</animal_url>
</item>
</items>
HTML
<div class="list-h">
</div>
Javascript
var s_string = 'bird';
$.ajax({
url: 'https://dl.dropboxusercontent.com/u/27854284/Stuff/Online/XML_animals.xml', // name of file you want to parse
dataType: "xml",
success: function parse(xmlResponse){
$(xmlResponse).find("item").each(function() {
var pr_id = $(this).find("animal_id").text();
var p_title = $(this).find("animal_title").text();
var p_category = $(this).find("animal_category").text();
var p_code = $(this).find("animal_code").text();
var p_img = $(this).find("animal_img").text();
var p_url = $(this).find("animal_url").text();
var p_gen_name = $(this).find("animal_generic").text();
var p_xml_string = p_title + p_gen_name, results_string = '', error;
if(s_string)
var s_string2 = s_string.replace("%20"," ");
//console.log(p_xml_string + s_string2);
if(p_xml_string.toLowerCase().indexOf(s_string2) > -1){
//console.log("FOUND : " + p_title);
results_string = '<div class="item"><div class="item-h"><a class="item-anchor" href="' + p_url + '"><div class="item-image"><img class="item-image-first" src="' + p_img + '" alt=""><div class="item-meta"><h2 class="item-title">' + p_title + '</h2><span class="item-arrow"></span></div></div></a></div></div>';
found_string = true; //// KEEP VALUES = TRUE OR FALSE IN AN ARRAY...GLOBAL ARRAY, AND THEN SEARCH THAT ARRAY FOR TRUE. IF ALL FALSE, SHOW ERROR.
}
if(found_string){
$('.list-h').append(results_string);
$('<div id="error_div"></div>').text("found");
}
}); //xmlResponse .each function end.
}, error: function(){console.log('Error: Animals info xml could not be loaded.');}
});
// START OF NOT FOUND SEARCH SCRIPT
$(window).load(function(){
var error_found = $('#error_div').text(); console.log(error_found);
setTimeout(function(){
if(error_found != 'found'){
var results_string = '<center>Your Search Query "<b>' + $.url().param('q').replace("%20"," ") + '" was not found!</b> Maybe you entered an invalid search query.</center>';
$('.list-h').append(results_string); }
}, 0);
});
// END OF NOT FOUND SEARCH SCRIPT
And here's the js fiddle with complete XML url: http://jsfiddle.net/mohitk117/B89Ms/
Please could someone help me out regarding this? Thanks!
Some changes may sort out your problem
Add a div in your html
<div id="error_div"></div>
Change below code
if (s_string) var s_string2 = s_string.replace("%20", " ");
//console.log(p_xml_string + s_string2);
if (p_xml_string.toLowerCase().indexOf(s_string2) > -1) {
to
var s_string2='';
if (s_string) s_string2 = s_string.replace("%20", " ");
if (s_string2 && p_xml_string.toLowerCase().indexOf(s_string2) > -1) {
Change found_string code like,
if (found_string) {
$('.list-h').append(results_string);
$('#error_div').text("found");
}
Optionally add css for error_div
#error_div {
color:red;
}
Live Demo
Updated success code
var found_string = false; // define found_string globally
$(xmlResponse).find("item").each(function () {
var pr_id = $(this).find("animal_id").text();
var p_title = $(this).find("animal_title").text();
var p_category = $(this).find("animal_category").text();
var p_code = $(this).find("animal_code").text();
var p_img = $(this).find("animal_img").text();
var p_url = $(this).find("animal_url").text();
var p_gen_name = $(this).find("animal_generic").text();
var p_xml_string = p_title + p_gen_name,
results_string = '',
error;
var s_string2 = '';
if (s_string) s_string2 = s_string.replace("%20", " ");
if (s_string2 && p_xml_string.toLowerCase().indexOf(s_string2) > -1) {
//console.log("FOUND : " + p_title);
results_string = '<div class="item"><div class="item-h"><a class="item-anchor" href="' + p_url + '"><div class="item-image"><img class="item-image-first" src="' + p_img + '" alt=""><div class="item-meta"><h2 class="item-title">' + p_title + '</h2><span class="item-arrow"></span></div></div></a></div></div>';
found_string = true; //// KEEP VALUES = TRUE OR FALSE IN AN ARRAY...GLOBAL ARRAY, AND THEN SEARCH THAT ARRAY FOR TRUE. IF ALL FALSE, SHOW ERROR.
}
if (found_string) { // if found then append in list
$('.list-h').append(results_string);
}
}); //xmlResponse .each function end.
if (found_string) { // if found then empty error div
$('#error_div').text("");
} else { // else show error text or not found
$('#error_div').text("not found");
}
Updated Found Demo and Not Found Demo
I'm a bit uncertain of how everything fits together because the javascript code is not self-explanatory. But, can you start by addressing this issue here...?
if(s_string)
var s_string2 = s_string.replace("%20"," ");
//console.log(p_xml_string + s_string2);
if(p_xml_string.toLowerCase().indexOf(s_string2) > -1){
s_string2 variable is out of scope when you use it in this expression...
if(p_xml_string.toLowerCase().indexOf(s_string2) > -1){
What were you trying to do there? The expression above will always evaluate to false because s_string2 is undefined. In other words, whatever processing you are doing inside that if block will never be reached
Again, this variable is instantiated and disposed at the very same time...
if(s_string)
var s_string2 = s_string.replace("%20"," "); //<--- This variable's lifecycle ends here
and, this expression will always be false until you address the variable issue above...
if(p_xml_string.toLowerCase().indexOf(s_string2) > -1)

Categories

Resources