jQuery appending to a dynamically created div - javascript

Trying to add a save/load feature using JSON to a diagram that uses jsPlumb. The save feature works like a charm however the load feature is not able to replicate full initial saved state. That is, the problem occurs when jQuery is trying to append to a freshly/dynamically created div.
The jsfiddle has the following functionality:
I can add projects which are div containers. Inside these I can add tasks by clicking on the green projects.
http://jsfiddle.net/9yej6/1/
My saving code plugins everything into an array which then becomes a string (using JSON).
$('#saveall').click(function(e) {
// Saving all of the projects' parameters
var projects = []
$(".project").each(function (idx, elem) {
var $elem = $(elem);
projects.push({
blockId: $elem.attr('id'),
positionX: parseInt($elem.css("left"), 10),
positionY: parseInt($elem.css("top"), 10)
});
});
// Saving all of the tasks' parameters
var tasks = []
$(".task").each(function (idx, elem) {
var $elem = $(elem);
tasks.push({
blockId: $elem.attr('id'),
parentId: $elem.parent().attr('id')
});
});
// Convert into string and copy to textarea
var flowChart = {};
flowChart.projects = projects;
flowChart.tasks = tasks;
var flowChartJson = JSON.stringify(flowChart);
$('#jsonOutput').val(flowChartJson);
});
The load code does the same in reverse.
$('#loadall').click(function(e) {
// Delete everything from the container
$('#container').text("");
// Convert textarea string into JSON object
var flowChartJson = $('#jsonOutput').val();
var flowChart = JSON.parse(flowChartJson);
// Load all projects
var projects = flowChart.projects;
$.each(projects, function( index, elem ) {
addProject(elem.blockId);
repositionElement(elem.blockId, elem.positionX, elem.positionY)
});
// Try to load all tasks
var tasks = flowChart.tasks;
$.each(tasks, function( index, elem ) {
//Problem occurs here, I am unable to reference the created project
$(elem.parentId).text('This is a test');
addTask(elem.parentId, 0);
});
});
Basically, what's not working is the $(parentId).append(newState); line 75 in the jsFiddle, I can't seem to reference that div because it was just created using jquery ?
edit:
More specifically, I make use of these functions to create actual project and task divs
function addProject(id) {
var newProject = $('<div>').attr('id', id).addClass('project').text(id);
$('#container').append(newProject);
jsPlumb.draggable(newProject, {
containment: 'parent' });
}
function addTask(parentId, index) {
var newState = $('<div>').attr('id', 'state' + index).addClass('task').text('task ' + index);
$(parentId).append(newState);
}

It should be:
$('#' + parentId).append(newState);
To search for an ID in a jQuery selector, you need the # prefix.

Related

Extract field value present in javascript of a webpage

This is the script present in the html web-page.
jQuery(function($) {
new Shopify.OptionSelectors('productSelect', {
product: {
"id":626976579,
"title":"changedMacbook Air",
"handle":"macbook-air",
"description":"\u003cp\u003elightweight \u003c\/p\u003e\n\u003cp\u003eawesome performance\u003c\/p\u003e\n\u003cp\u003ewow display\u003c\/p\u003e\nHello World626976579[\"78000.00\"] [\"78000.00\"]\\n[\"78000.00\"] [\"78000.00\"]\u003cbr\u003e[\"78000.00\"]\u003cbr\u003e626976579\u003cbr\u003e626976579\u003cbr\u003e626976579",
"published_at":"2015-05-25T02:39:00-04:00",
"created_at":"2015-05-25T02:40:44-04:00",
"vendor":"Test_Store",
"type":"Computers",
"tags":[],
"price":7800000,
"price_min":7800000,
"price_max":7800000,
"available":true,
"price_varies":false,
"compare_at_price":null,
"compare_at_price_min":0,
"compare_at_price_max":0,
"compare_at_price_varies":false,
"variants":[{"id":1754837635,"title":"Default Title","options":["Default Title"],"option1":"Default Title","option2":null,"option3":null,"price":7800000,"weight":800,"compare_at_price":null,"inventory_quantity":-29,"inventory_management":null,"inventory_policy":"deny","available":true,"sku":"20","requires_shipping":true,"taxable":true,"barcode":"","featured_image":null}],"images":["\/\/cdn.shopify.com\/s\/files\/1\/0876\/1234\/products\/overview_wireless_hero_enhanced.png?v=1432536113"],"featured_image":"\/\/cdn.shopify.com\/s\/files\/1\/0876\/1234\/products\/overview_wireless_hero_enhanced.png?v=1432536113","options":["Title"],"content":"\u003cp\u003elightweight \u003c\/p\u003e\n\u003cp\u003eawesome performance\u003c\/p\u003e\n\u003cp\u003ewow display\u003c\/p\u003e\nHello World626976579[\"78000.00\"] [\"78000.00\"]\\n[\"78000.00\"] [\"78000.00\"]\u003cbr\u003e[\"78000.00\"]\u003cbr\u003e626976579\u003cbr\u003e626976579\u003cbr\u003e626976579"},
onVariantSelected: selectCallback,
enableHistoryState: true
});
How the value of "title" field be accessed, which here it is "changedMacbook Air" via my own JavaScript?
Thanks in advance.
I don't know if it will work but try
var myProduct = new Shopify.OptionSelectors('productSelect', {
....
})
then try
console.log(myProduct)
or you can try this:
$(document).ready(function(e){
console.log(document.title);
})
I think you might have to pass it through the callback.
$('#productSelect').on('change', function(e) {
var t = e.target || e.srcElement,
title = t.title.value;
selectCallback(title);
break;
}
}
});
//If you want to trigger it right away for some reason, just use this...
$("#productSelect").change();
Look for the code for option_selection.js in your products template or somewhere in your Snippets, Assets, or Templates. See this fiddle for an example of what the code looks like. option_selection.js
You might also want to check this link, it's setting up an onchange event on the product variants. I'm not sure what your ultimate goal is but I see you are working with product options and variants so it might be helpful.
You can modify option_selection.js if you need to, but more than likely you will just need some jquery in the document.ready.
Here is an example from option_selection.js that builds the names of each selector. Though you probably don't need to modify this, see link above.
Shopify.OptionSelectors.prototype.buildSelectors = function() {
for (var t = 0; t < this.product.optionNames().length; t++) {
var e = new Shopify.SingleOptionSelector(this, t, this.product.optionNames()[t], this.product.optionValues(t));
e.element.disabled = !1, this.selectors.push(e)
}
var o = this.selectorDivClass,
i = this.product.optionNames(),
r = Shopify.map(this.selectors, function(t) {
var e = document.createElement("div");
if (e.setAttribute("class", o), i.length > 1) {
var r = document.createElement("label");
r.htmlFor = t.element.id, r.innerHTML = t.name, e.appendChild(r)
}
return e.appendChild(t.element), e
});
return r
},

Do something when all dynamically created images have loaded

What I'm trying to do is create a dynamic wall of images.
What I'm doing is this:
Call an API to get some response. Create an array of objects based on response
Based on the array, make HTML elements for each object where there's an img in it too.
When all of these HTML elements are created, attach it to the DOM, and call a final function.
This is what I have so far (truncated to get the point across):
EDIT: code has changed a bit. scroll to bottom of question for link to current code.
// based on one post, construct the html and return it
function getOneHtml(post, w) {
console.log("getting one html");
var outerDiv = $("<div>", {class: "brick"});
outerDiv.width(w);
var img = $("<img />");
img.attr("src", post.img_src);
img.on('load', function() {
console.log("img loaded");
var ratio = this.width / w;
h = this.height / ratio;
$(this).css({'height': h});
// ...
// ...
// create the element
// an alternative I'm using for now is directly append
// the created HTML onto the page, but that results
// in a kinda messy interface.
return outerDiv[0].outerHTML;
});
}
// queries an api and then calls callback after everything is done
function requestData(subreddit, callback) {
// array of objects with link to image, post title, link to reddit
posts = [];
var w = $(window).innerWidth() / 3,
html = ''; // holds all of the inner HTML for all elements
$.get("url here", function(data) {
var arr = data.data.children;
arr.forEach(function(res_post) {
console.log("looping in requestData");
// prepare a post object
// ...
// ...
html += getOneHtml(post, w); // get the HTML for this post
});
// this should happen after everything else is done
console.log("calling callback");
callback(html);
});
}
// complete the DOM
function makeWall(html) {
console.log("making wall");
// do stuff
}
Now the trace of the program in console is this:
looping in requestData
getting one html
looping in requestData
getting one html
... // bunch of times
calling callback
making wall
(20) img loaded
So now the problem is that the HTML isn't prepared until each image is loaded, and so it doesn't actually get attached to the DOM.
How can I make sure that things happen in order in which I want them to? I tried refactoring code into more of an async style but that didn't work (not my strongest point).
I also tried looking at $.Deferred but I don't understand it, and how to integrate it into my code.
Any help is appreciated.
EDIT:
I think it might help to see what I'm doing: http://karan.github.io/griddit/
When you load, I want the images to load first, and then fade in. Currently, they show up, then hide and then fade in. Here's the source: https://github.com/karan/griddit/blob/gh-pages/js/main.js.
Also, if you scroll down one or two pages, then scroll back up, some images show up behind others.
You can use .done(), as explained in the jQuery API documentation on .done() specifically explains how to use .done() with $.get().
It's as simple as:
$.get( "test.php" ).done(function() {
alert( "$.get succeeded" );
});
Concretely...
As the API documentation link provided above indicates, you can daisy chain .done() calls together.
$.get(url,handler).done(function(){console.log('calling callback')},callback);
Note, Not certain about functionality of included plugins, i.e.g., #grid layout,
css, etc. image width, height and #grid layout not addressed, save for existing pieces re-composed in attempt at flow clarity.
Piece below solely to fulfill // Do something when all dynamically created images have loaded requirement. See console at jsfiddle
Note also, piece at jsfiddle format issue. In order to test piece, drew in 2 plugins from links at original post. Tried jsfiddle's TidyUp feature, which inserted linebreaks.
Piece may need some re-formatting; though current jsfiddle does provide callback functionality, as per original post. Again, see console. Thanks for sharing.
updated
$(function() {
// the name of the last added post
var last_added = '';
// to control the flow of loading during scroll var scrollLoad = true;
var q = 'cats';
var callbacks = $.Callbacks();
// callback,
// Do something when all dynamically created images have loaded
var callback = function (cb) {
return console.log( cb||$.now() )
};
callbacks.add(callback);
function getOneHtml(post, w, count){
var img = $("<img>", {
"src" : post.img_src,
"width" : w
});
img.on('load', function(e) {
var ratio = e.target.width / w;
h = e.target.height / ratio;
$(e.target).css('height',h)
});
var link = $("<a>", {
"href" : post.permalink,
"target" : "_blank",
"html" : img
});
var outerDiv = $("<div>", {
"class" : "brick",
"style" : "width:" + w
});
$.when($(outerDiv).appendTo("#grid"),
$(link),
count)
.then(function(div, _link, _count) {
// `image` `fadeIn`; adjustable
$(_link).appendTo($(div)).hide(0).fadeIn(2000);
return _count
})
.always(function(_count){
callbacks.fireWith(window, [_count + " images appended to grid at " + $.now()])
});
};
function requestData(subreddit,callback) {
//array of objects with link to image, post title,link to reddit
posts=[];
var w = $(window).innerWidth() / 3;
html = '';
$.ajax({
type : 'get',
url : "http://api.reddit.com/r/" + subreddit + "/hot.json?&after=" + last_added,
beforeSend : function () {
$("#searchterm").addClass("loadinggif");
},
complete : function () {
$("#searchterm").removeClass("loadinggif");
},
success : function (data) {
var arr = data.data.children;
var count = null;
arr.forEach(function(res_post) {
if(!res_post.data.is_self&&(/\.(gif|jpg|jpeg|tiff|png)$/i).test(res_post.data.url)) {
// `images` count
++count;
var post = {
'title' : res_post.data.title,
'img_src': res_post.data.url,
'name' : res_post.data.name,
'permalink': 'http://reddit.com' + res_post.data.permalink
};
getOneHtml(post, w, count);
}
last_added = res_post.data.name;
});
scrollLoad = true;
// callback,
// Do something when all dynamically created images have loaded
// see `console`; adjustable
callbacks.fireWith( window, [$(".brick img").size() + " appended to grid, callback at " + $.now()]);
}});
}
// function makeWall() {}
})
jsfiddle http://jsfiddle.net/guest271314/ggsY9/

What event is triggered when a HTML5 Adobe Extension Panel is collapsed?

I am working on a HTML5 Adobe Extension that needs to load data from LocalStorage into some 's but for the life of me I can't figure out wether the panel is being collapsed or closed or what happens with it. The list items are generated dinamically.
I would also need an ideea to save data upon exit so that the list elements inside the UL can be saved and retrieved when PS starts again. So far I noticed that the host i a chrome type browser that supports a lot of stuff, including localstorage. However, I've not seen a dead simple tutorial for saving ul items but only for variables and strings.
right now I'm unable to save or retrieve the data from localstorage.
here is my code so far.
$(document).ready(function(){
var task = {
"name" : "",
"description" : "",
"project" : ""
};
$('#saveData').css("visibility", "hidden");
$('#btnMarkAsDone').css("visibility","hidden");
var toBeDone = Array();
var wasDone = Array();
$( window ).load(function() {
for(var i = 0;i < toBeDone.length;i++){
$('#todo').append('<li class="todo-item">'+toBeDone[i]+'</li>');
}
for(var i = 0; i < wasDone.length; i++){
$('#done').append('<li class="completed">'+wasDone[i]+'</li>');
}
});
$( window ).width(function() {
});
$("#btnAddTask").click(function(){
var oName = task.name;
var oProject = task.project;
var oDescription = task.description;
var taskname = $("#txtTaskName").val();
var taskproject = $("#txtTaskProj").val();
var taskdescription = $("#txtTaskDesc").val();
oName = taskname;
oProject = taskproject;
oDescription = taskdescription;
var input = "<b>Task: </b>"+oName+" | "+"<b>PSD: </b>"+oProject+" | "+"<b>Desc: </b>"+oDescription;
$("#todo").append('<li class="todo-item">'+input+'</li>');
});
$("#todo").on('click','li',function(){
$(this).addClass('complete');
$("#done").append(this);
});
$("#done").on('click','li',function(){
$(this).remove();
});
$("#saveData").click(function(){
if(localStorage['todo']){
toBeDone = JSON.parse(localStorage['todo']);
}if(localStorage['done']){
wasDone = JSON.parse(localStorage['done']);
}
});
$(function() {
$("button").button();
});
});
Fixed the localStorage part:
$("#saveData").click(function(){
var toDo = $('#todo').html();
var finished = $('#done').html();
localStorage.setItem('todo',toDo);
localStorage.setItem('done',finished);
});
$(window).load(function() {
$("#todo").html(localStorage.getItem('todo'));
$("#done").html(localStorage.getItem('done'));
});
Still need to find out what kind of event is fired when a window is collapsed though. I appreciate any help !

How do I update html element in a string inside an object?

I'm having a hard time doing something that seems really simple.
I have a javascript object:
var main = {
pages : {
"123" : {
"content": "<div><p>The div</p></div><nav><p>The nav</p></nav>",
"foo":"bar"
},
"456" : {
"content": "<div><p>The div</p></div><nav><p>The nav</p></nav>",
"foo":"bar"
}
}
};
I'm trying the following code:
$(function(){
var p = main.pages;
$.each(p,function(i,el){
var c = p[i].content;
var newc = $(c).find('nav').html('<p>New content</p>');
//console.log(c);
//console.log(newc);
});
//console.log(p)
});
To make my object look like:
var main = {
pages : {
"123" : {
"content": "<div><p>The div</p></div><nav><p>New content</p></nav>",
"foo":"bar"
},
"456" : {
"content": "<div><p>The div</p></div><nav><p>New content</p></nav>",
"foo":"bar"
}
}
};
But I'm having a hard time doing it. What am I missing?
I have set up the former example in jsfiddle
I do understand that it's generally not a good idea trying to manipulate strings as dom elements but I have no other choice since the object comes from a RESTful server and it doesn't make much sense to inject the html in the current page for that.
You can actually build the HTML in jQuery without appending it into the DOM.
$(function () {
var p = main.pages;
//a temporary div
var div = $('<div>');
$.each(p, function (i, el) {
//append to div, find and replace the HTML
div.append(p[i].content).find('nav').html('<p>New content</p>');
//turn back into a string and store
p[i].content = div.html();
//empty the div for the next operation
div.empty();
});
console.log(p);
});
Because $(p[i].content) is not one element but two, so based on your code:
var tmp = $(p[i].content);
tmp.eq(1).html('<p>new content');
console.log(tmp.html());

Add new rows to jqGrid Treegrid model

We've created a jqGrid TreeGrid that represents a filesystem, where branches are folders and leafs are files. We've implemented functionality within the TreeGrid to create new "files" by using addChildNode which works well enough. However, we also want to add functionality to create new folders. Our script works which creates new folders, but they are not immediately displayed on the TreeGrid unless it or the page is reloaded. However, reloading the TreeGrid will collapse all the folders, which is particularly annoying.
Is there a way to selectively refresh the nodes of the TreeGrid, or to add a new branch in that is functional? I've seen some partial documentation on addJSONData, but using this function completely purges the TreeGrid until refresh. I've also attempted to use addChildNode and change certain properties, and I've tried to add in the row manually using DOM manipulation; however, both of these methods break the node that was inserted.
Edit:
var grid = $("#grid");
grid.jqGrid({
treeGrid: true,
treeGridModel: "adjacency",
ExpandColumn: 'name',
ExpandColClick: true,
url:"",
datatype:"json",
colNames:['id','Name','Authorization','Views','Uri'],
colModel:[ {name:'id', index:'id', hidden:true, key:true},
{name:'name', index:'name', sorttype:"text", width:3, sortable:false},
{name:'auth',index:'auth', sorttype:"text", sortable:false, hidden:true},
{name:'views',index:'views', sorttype:"integer", width:1, sortable:false, align:"center"},
{name:'uri',index:'uri',sorttype:'text',sortable:false,hidden:true}],
jsonReader:{ root:"rows"
,page:"page"
,total:"total"
,records:"records"
,repeatitems:false
,cell:""
,id:"0"
,userdata:""
},
multiselect:false,
autowidth:true,
height:"auto",
sortable:false,
toppager:true,
hidegrid: false,
loadui: 'block',
pager:"#grid_pager",
caption: "Files",
});
A returned JSON request for the new folder looks something like this:
ret = {"error":"","total":1,"page":1,"records":1,"rows":[{"id":"1113","name":"test","uri":"accounting\/test\/","parent":1,"isLeaf":false,"expanded":true,"loaded":true}]}
Which I attempt to add in using:
grid[0].addJSONData(ret);
The initial data that is loaded is sent as JSON:
{"rows":[
{"id":"1","uri":"afolder\/","parent_id":"0","name":"afolder","level":0,"parent":"0","isLeaf":"false"},
{"id":"4","uri":"bfolder\/","parent_id":"0","name":"bfolder","level":0,"parent":"0","isLeaf":"false"},
{"id":"7","uri":"cfolder\/","parent_id":"0","name":"cfolder","level":0,"parent":"0","isLeaf":"false"},
{"id":"20","uri":"dfolder\/","parent_id":"0","name":"dfolder","level":0,"parent":"0","isLeaf":"false"},
{"id":"48","uri":"efolder\/","parent_id":"0","name":"efolder","level":0,"parent":"0","isLeaf":"false"},
{"id":"179","uri":"ffolder\/","parent_id":"0","name":"ffolder","level":0,"parent":"0","isLeaf":"false"},
{"id":"182","uri":"gfolder\/","parent_id":"0","name":"gfolder","level":0,"parent":"0","isLeaf":"false"},
{"id":"186","uri":"hfolder\/","parent_id":"0","name":"hfolder","level":0,"parent":"0","isLeaf":"false"},
{"id":"201","uri":"ifolder\/","parent_id":"0","name":"ifolder","level":0,"parent":"0","isLeaf":"false"},
{"id":"239","uri":"jfolder\/","parent_id":"0","name":"jfolder","level":0,"parent":"0","isLeaf":"false"},
{"id":"253","uri":"kfolder\/","parent_id":"0","name":"kfolder","level":0,"parent":"0","isLeaf":"false"},
{"id":"262","uri":"lfolder\/","parent_id":"0","name":"lfolder","level":0,"parent":"0","isLeaf":"false"},
{"id":"274","uri":"mfolder\/","parent_id":"0","name":"mfolder","level":0,"parent":"0","isLeaf":"false"}
]}
The demo shows how to use addChildNode method to add tree node. I added in the JSON data which you posted the "loaded":true part because I use in the test no server components and I want to load the treegrid at once.
To show that you should be very careful with ids of the new added row I added two buttons in the demo: "Insert tree node" and "Insert tree node with unique rowid". The first button use the id="1113" from the data which you posted. One click on the button work correct. the second click will insert rows having id duplicates which will be an error. The error you can see different in different web browsers. The second button use $.jgrid.randId() to generate unique rowid. It is probably not an option in your scenario, but it works perfect in case of local tree grid (like in my demo).
Another problem is that you use "parent":"0" in your demo for the root elements. Correct will be "parent":null or "parent":"null" (see the answer). Moreover the property with the name "parent_id" will be ignored. I removed from the demo some settings, so that local sorting can be used in the treegrid.
We solved this problem by extending the functionality of the jqGrid source. First we created a function that could delete all of the child nodes of a particular folder (both folders/branches and files/leaves), so that we could reload them and hence get the latest set of children. This function takes an integer rowid just like delTreeNode().
delChildren : function (rowid) {
return this.each(function () {
var $t = this, rid = $t.p.localReader.id,
left = $t.p.treeReader.left_field,
right = $t.p.treeReader.right_field, myright, width, res, key;
if(!$t.grid || !$t.p.treeGrid) {return;}
var rc = $t.p._index[rowid];
if (rc !== undefined) {
// nested
myright = parseInt($t.p.data[rc][right],10);
width = myright - parseInt($t.p.data[rc][left],10) + 1;
var dr = $($t).jqGrid("getFullTreeNode",$t.p.data[rc]);
if(dr.length>0){
for (var i=0;i<dr.length;i++){
if(dr[i][rid] != rowid)
$($t).jqGrid("delRowData",dr[i][rid]);
}
}
if( $t.p.treeGridModel === "nested") {
// ToDo - update grid data
res = $.jgrid.from($t.p.data)
.greater(left,myright,{stype:'integer'})
.select();
if(res.length) {
for( key in res) {
res[key][left] = parseInt(res[key][left],10) - width ;
}
}
res = $.jgrid.from($t.p.data)
.greater(right,myright,{stype:'integer'})
.select();
if(res.length) {
for( key in res) {
res[key][right] = parseInt(res[key][right],10) - width ;
}
}
}
}
});
},
Then, we created a function to force reloading of a certain node (folder).
reloadNode: function(rc) {
return this.each(function(){
if(!this.grid || !this.p.treeGrid) {return;}
var rid = this.p.localReader.id;
$(this).jqGrid("delChildren", rc[rid]);
var expanded = this.p.treeReader.expanded_field,
parent = this.p.treeReader.parent_id_field,
loaded = this.p.treeReader.loaded,
level = this.p.treeReader.level_field,
lft = this.p.treeReader.left_field,
rgt = this.p.treeReader.right_field;
var id = $.jgrid.getAccessor(rc,this.p.localReader.id);
var rc1 = $("#"+id,this.grid.bDiv)[0];
rc[expanded] = true;
$("div.treeclick",rc1).removeClass(this.p.treeIcons.plus+" tree-plus").addClass(this.p.treeIcons.minus+" tree-minus");
this.p.treeANode = rc1.rowIndex;
this.p.datatype = this.p.treedatatype;
if(this.p.treeGridModel == 'nested') {
$(this).jqGrid("setGridParam",{postData:{nodeid:id,n_left:rc[lft],n_right:rc[rgt],n_level:rc[level]}});
} else {
$(this).jqGrid("setGridParam",{postData:{nodeid:id,parentid:rc[parent],n_level:rc[level]}} );
}
$(this).trigger("reloadGrid");
rc[loaded] = true;
if(this.p.treeGridModel == 'nested') {
$(this).jqGrid("setGridParam",{postData:{nodeid:'',n_left:'',n_right:'',n_level:''}});
} else {
$(this).jqGrid("setGridParam",{postData:{nodeid:'',parentid:'',n_level:''}});
}
});
},
This is the same as expandNode() save for that it does not check if the node was expanded to begin with, and forces it to send an AJAX request for the child elements of that node. This way, we always have the latest children.
Finally, we fixed a small bug in getRowData(), which prevented us from using it to supply the record argument to either expandNode() or our newly created reloadNode(). The issue was that the _id_ field in the JSON return was never created or filled. Adding that in fixed both expandNode() and reloadNode() The following is the changed source. Not ideal, but it works.
getRowData : function( rowid ) {
var res = {}, resall, getall=false, len, j=0;
this.each(function(){
var $t = this,nm,ind;
if(typeof(rowid) == 'undefined') {
getall = true;
resall = [];
len = $t.rows.length;
} else {
ind = $t.rows.namedItem(rowid);
if(!ind) { return res; }
len = 2;
}
while(j<len){
if(getall) { ind = $t.rows[j]; }
if( $(ind).hasClass('jqgrow') ) {
$('td',ind).each( function(i) {
nm = $t.p.colModel[i].name;
if ( nm !== 'cb' && nm !== 'subgrid' && nm !== 'rn') {
if($t.p.treeGrid===true && nm == $t.p.ExpandColumn) {
res[nm] = $.jgrid.htmlDecode($("span:first",this).html());
} else {
if($t.p.colModel[i].key != undefined && $t.p.colModel[i].key == true)
{
try {
res["_" + nm + "_"] = $.unformat(this,{rowId:ind.id, colModel:$t.p.colModel[i]},i);
} catch (e){
res["_" + nm + "_"] = $.jgrid.htmlDecode($(this).html());
}
}
try {
res[nm] = $.unformat(this,{rowId:ind.id, colModel:$t.p.colModel[i]},i);
} catch (e){
res[nm] = $.jgrid.htmlDecode($(this).html());
}
}
}
});
if(getall) { resall.push(res); res={}; }
}
j++;
}
});
return resall ? resall: res;
},
Finally, we pull this all together as follows, with a JSON return object from creating a folder such as
{{"id":"1267", "name":"test15", "uri":"sample1\/test15\/", "parent_id":1, "parent":1, "isLeaf":false}
We call the function like
var parentid = ret.rows[0].parent;
var parent = grid.jqGrid('getRowData', parentid);
grid.jqGrid('reloadNode', parent);
The functions will delete all the child nodes of parent, then send an AJAX request for the new, updated list from the database. I'm going to push this onto the jqGrid Github if possible, since a reload function maybe useful for many people. I've posted it in here in case it isn't approved.

Categories

Resources