Page 1 of 2

How to call AJAX from module

Posted: Fri Feb 11, 2011 8:48 pm
by cve
Hi guys, I develop my module which have categories tab for manage categories and I want to use wonderful plugin jsTree for jquery (http://www.jstree.com) and I have that code in js:

Code: Select all

$(function(){
    $('#tree').tree({
        data : {
            async: true,
            type: 'json',
            opts: {
                method: 'GET',
                url: WHAT SHOULD I PUT HERE???
            }
        }
    });
});
My function which generate tree structure in json format is in file named "action.ajax_tree.php" under my module's named folder:

Code: Select all

<?php
echo json_encode($this->_getNestify($this->_getTree()));
?>
And inside categories tab is pretty simple code which will be display tree build from jsTree:

Code: Select all

<div id="tree"></div>
And my question is how can I get this URL in my js code...? I'm completely helpless...

Re: How to call AJAX from get url of module

Posted: Sat Feb 12, 2011 11:30 am
by vilkis

Code: Select all

$url = $this->CreateLink($id, 'ajax_tree', $returnid, '', $params, '', true);
vilkis

Re: How to call AJAX from get url of module

Posted: Sun Feb 13, 2011 5:29 am
by cve
I entered that code:

Code: Select all

$url = $this->CreateLink($id, 'tree', $returnid, '', array('disable_theme' => 'true', 'showtemplate' => 'false')
it generates url link in jquery code (this is snippet code from jstree, because whole code is not readable):

Code: Select all

"json_data" : {
				
				"ajax" : {
					// the URL to fetch the data
					"url" : "http://cms.ionic.pl/admin/moduleinterface.php?mact=Sklep,m1_,tree,0&sp_=443d35f4&m1_disable_theme=true&m1_showtemplate=false",
					
					"data" : function (n) {
						// the result is fed to the AJAX request `data` option
						return {
							"operation" : "get_children",
							"id" : n.attr ? n.attr("id").replace("node_","") : 1
						};
					}
				}
			}
and when i fire up my admin module panel and whatching what's going on in firebug XHR I get this:
http://img1.uploadscreenshot.com/images ... 1-orig.jpg
It's require login... but why??? When I try fire up url with params operation=get_children and id=1:

Code: Select all

http://cms.ionic.pl/admin/moduleinterface.php?mact=Sklep,m1_,tree,0&sp_=443d35f4&m1_disable_theme=true&m1_showtemplate=false&operation=get_children&id=1
it's also require login... I don't know what's going wrong... :/

Re: How to call AJAX from module

Posted: Sun Feb 13, 2011 1:07 pm
by vilkis
I do not know what XHR means. Does your URL really consist of & and & ?

vilkis

Re: How to call AJAX from module

Posted: Sun Feb 13, 2011 7:42 pm
by cve
XHR is xml http request, it is such tab in firebug where I can see whats happen when ajax request comes... And yes, my url contains amp's what I was typing in my earlier post in js code snippet...

Re: How to call AJAX from module

Posted: Mon Feb 14, 2011 7:05 am
by vilkis
ok - try organize your action as a frontend action. And generate an url as frontend - it means you have to set $returnid to value of real page id before generating the url. This solution is not secure, as anybody can view output of such an action if he guess an url of your action.
I do not know another solution.
vilkis

Re: How to call AJAX from module

Posted: Mon Feb 14, 2011 2:17 pm
by cve
Can you explain me, what do you mean? Should I generete url throught CreateFrontentLink method??? I think, I have organized structure of files in my module, my file with action is called action.tree.php

Re: How to call AJAX from module

Posted: Mon Feb 14, 2011 2:46 pm
by vilkis
generate url as follows

Code: Select all

$sql = 'SELECT content_id FROM ' . cms_db_prefix() . 'content WHERE active = 1';
$returnid = $db->GetOne($sql);
$parms = array('showtemplate' => 'false');
$url = $this->CreateLink($id, 'tree', $returnid, '', $parms, true);
I have not checked the code for errors.

This should work if you do not use the function CheckPermission in file action.tree.php

vilkis

Re: How to call AJAX from module

Posted: Mon Feb 14, 2011 3:22 pm
by cve
It's not working... :/ Where can I see how to make ajax requests and links in module with cms made simple???

Re: How to call AJAX from module

Posted: Mon Feb 14, 2011 3:38 pm
by vilkis
What url did you get?
vilkis

Re: How to call AJAX from module

Posted: Mon Feb 14, 2011 3:42 pm
by cve
That code:

Code: Select all

$url = $this->CreateLink($id, 'tree', 2, '', array('disable_theme' => 'true'), '', true, false);
generates:

Code: Select all

http://cms.ionic.pl/index.php?mact=Sklep,cntnt01,tree,0&cntnt01disable_theme=true&cntnt01returnid=2
And now request is ok, but nothink is returned

Re: How to call AJAX from module

Posted: Mon Feb 14, 2011 3:46 pm
by vilkis
remove function CheckPerrmision() from action.tree.php

Re: How to call AJAX from module

Posted: Mon Feb 14, 2011 3:48 pm
by vilkis
secondly
use 'showtemplate' => 'false' and not 'disable_theme' => 'true'

vilkis

Re: How to call AJAX from module

Posted: Mon Feb 14, 2011 3:59 pm
by cve
my action.tree.php:

Code: Select all

<?php
if (!isset($_REQUEST["operation"]))
    die();

require_once ("JstreeDatabase.php");
require_once ("Jstree.php");

$jstree = new json_tree();

if (isset($_GET["reconstruct"])) {
    $jstree->_reconstruct();
    die();
}
if (isset($_GET["analyze"])) {
    echo $jstree->_analyze();
    die();
}

if ($_REQUEST["operation"] && strpos("_", $_REQUEST["operation"]) !== 0 && method_exists($jstree, $_REQUEST["operation"])) {
    header("HTTP/1.0 200 OK");
    header('Content-type: text/json; charset=utf-8');
    header("Cache-Control: no-cache, must-revalidate");
    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
    header("Pragma: no-cache");
    echo $jstree->{$_REQUEST["operation"]}($_REQUEST);
    die();
}
header("HTTP/1.0 404 Not Found");
 
my tab "kategorie" in my admin panel includes:

Code: Select all

<?php
if (!isset($gCms)) exit;;
$url = $this->CreateLink($id, 'tree', 2, '', array('disable_theme' => 'true', 'showtemplate' => 'false'), '', true, true);
//$baseUrl = 'http://cms.ionic.pl/admin/';
//$url2 = substr($url, strlen($baseUrl));
//if (!$this->CheckPermission('Use Sklep')) exit;
?>
<div id="link_to_help">
    <a href="#" id="toggle_help"><img src="<?php echo $this->GetModuleURLPath() ?>/img/help.png" alt="" />Wyświetl pomoc</a>
</div>
<div id="help">
    <div id="add">
        <h2>Dodawanie nowej kategorii</h2>
        <p>Jeśli chcesz dodać nową kategorię wystarczy, że klikniesz lewym przyciskiem myszy na
        kategorię do której chcesz dodać nową i prawym przyciskiem myszy z menu kontekstowego
        wybierzesz Create, wpiszesz nazwę i wciśniesz Enter. Podobnie działa przycisk Dodaj.</p>
        <img src="<?php echo $this->GetModuleURLPath() ?>/img/help/add.png" alt="" />
    </div>
    <div id="dnd">
        <h2>Przenoszenie kategorii</h2>
        <p>Przeniesienie dowolnej kategorii jest równie łatwe jak dodawanie nowej. Po prostu chwyć lewym
        przyciskiem myszki kategorię i przenieś starannie nad żądane miejsce po czym puść przycisk i
        odczekaj chwilkę, aby system mógł wykonać odpowiednie obliczenia. Możliwe jest również przenoszenie
        całych kategorii wraz z ich podkategoriami w taki sam sposób.</p>
        <img src="<?php echo $this->GetModuleURLPath() ?>/img/help/dnd.png" alt="" />
    </div>
    <div id="add_sub">
        <h2>Dodawanie podkategorii</h2>
        <p>Aby dodać podkategorię dla istniejącej już kategorii kliknij na kategorię do ktorej chcesz dodać
        podkategorię i postępuj tak jak w celu dodawania nowej kategorii.</p>
        <img src="<?php echo $this->GetModuleURLPath() ?>/img/help/add_sub.png" alt="" />
    </div>
</div>
<div id="container">

<div class="buttons" style="height:30px; overflow:hidden;">
<!--<input type="button" id="add_default" value="Dodaj kategorię" style="display:block; float:left;"/>-->
<button type="button" id="add_default">
    <img src="<?php echo $this->GetModuleURLPath() ?>/img/add.png" alt="" />
    Dodaj
</button>
<button type="button" id="rename">
    <img src="<?php echo $this->GetModuleURLPath() ?>/img/page_white_edit.png" alt="" />
    Zmień nazwę
</button>
<button type="button" id="remove">
    <img src="<?php echo $this->GetModuleURLPath() ?>/img/delete.png" alt="" />
    Usuń
</button>
<button type="button" id="cut">
    <img src="<?php echo $this->GetModuleURLPath() ?>/img/cut.png" alt="" />
    Wytnij
</button>
<button type="button" id="copy">
    <img src="<?php echo $this->GetModuleURLPath() ?>/img/page_copy.png" alt="" />
    Kopiuj
</button>
<button type="button" id="paste">
    <img src="<?php echo $this->GetModuleURLPath() ?>/img/page_paste.png" alt="" />
    Wklej
</button>
<button type="button" id="clear_search">
    <img src="<?php echo $this->GetModuleURLPath() ?>/img/pencil_delete.png" alt="" />
    Wyczyść
</button>
<button type="button" id="search">
    <img src="<?php echo $this->GetModuleURLPath() ?>/img/page_go.png" alt="" />
    Szukaj
</button>
<input type="text" id="text" value="" style="display:block; float:right;" />
<!--<input type="button" id="rename" value="Zmień nazwę" style="display:block; float:left;"/>
<input type="button" id="remove" value="Usuń" style="display:block; float:left;"/>
<input type="button" id="cut" value="Wytnij" style="display:block; float:left;"/>
<input type="button" id="copy" value="Skopiuj" style="display:block; float:left;"/>
<input type="button" id="paste" value="Wklej" style="display:block; float:left;"/>
<input type="button" id="clear_search" value="Wyczyść" style="display:block; float:right;"/>
<input type="button" id="search" value="Szukaj" style="display:block; float:right;"/>-->

</div>

<!-- the tree container (notice NOT an UL node) -->
<div id="demo" class="demo"></div>
<!-- JavaScript neccessary for the tree -->
<__script__ type="text/javascript">
$(function () {
	// Settings up the tree - using $(selector).jstree(options);
	// All those configuration options are documented in the _docs folder
	$("#demo")
		.jstree({
                        core : {
                            strings : {
                                loading : "Ładuje kategorie...",
                                new_node : "Wpisz nazwę kateogorii"
                            }
                        },
			// the list of plugins to include
			"plugins" : [ "themes", "json_data", "ui", "crrm", "cookies", "dnd", "search", "types", "hotkeys", "contextmenu", "unique" ],
			// Plugin configuration

                        "themes" : {
                            "theme" : "apple",
                            "dots" : true,
                            "icons" : false
                        },
			// I usually configure the plugin that handles the data first - in this case JSON as it is most common
			"json_data" : {
				// I chose an ajax enabled tree - again - as this is most common, and maybe a bit more complex
				// All the options are the same as jQuery's except for `data` which CAN (not should) be a function
				"ajax" : {
					// the URL to fetch the data
					"url" : "<?php echo $url ?>",
					// this function is executed in the instance's scope (this refers to the tree instance)
					// the parameter is the node being loaded (may be -1, 0, or undefined when loading the root nodes)
					"data" : function (n) {
						// the result is fed to the AJAX request `data` option
						return {
							"operation" : "get_children",
							"id" : n.attr ? n.attr("id").replace("node_","") : 1
						};
					}
				}
			},
			// Configuring the search plugin
			"search" : {
				// As this has been a common question - async search
				// Same as above - the `ajax` config option is actually jQuery's object (only `data` can be a function)
				"ajax" : {
					"url" : "<?php echo $url ?>",
					// You get the search string as a parameter
					"data" : function (str) {
						return {
							"operation" : "search",
							"search_str" : str
						};
					}
				}
			},
			// Using types - most of the time this is an overkill
			// Still meny people use them - here is how
			"types" : {
				// I set both options to -2, as I do not need depth and children count checking
				// Those two checks may slow jstree a lot, so use only when needed
				"max_depth" : -2,
				"max_children" : -2,
				// I want only `drive` nodes to be root nodes
				// This will prevent moving or creating any other type as a root node
				"valid_children" : [ "drive" ],
				"types" : {
					// The default type
					"default" : {
						// I want this type to have no children (so only leaf nodes)
						// In my case - those are files
						"valid_children" : [ "default" ],
						// If we specify an icon for the default type it WILL OVERRIDE the theme icons
						"icon" : {
							"image" : "<?php echo $this->GetModuleURLPath() ?>/folder.png"
						}
					},
					// The `drive` nodes
					"drive" : {
						// can have files and folders inside, but NOT other `drive` nodes
						"valid_children" : [ "default" ],
						"icon" : {
							"image" : "<?php echo $this->GetModuleURLPath() ?>/root.png"
						},
						// those options prevent the functions with the same name to be used on the `drive` type nodes
						// internally the `before` event is used
						"start_drag" : false,
						"move_node" : false,
						"delete_node" : false,
						"remove" : false
					}
				}
			},
			// For UI & core - the nodes to initially select and open will be overwritten by the cookie plugin

			// the UI plugin - it handles selecting/deselecting/hovering nodes
			"ui" : {
				// this makes the node with ID node_4 selected onload
				"initially_select" : [ "node_4" ]
			},
			// the core plugin - not many options here
			"core" : {
				// just open those two nodes up
				// as this is an AJAX enabled tree, both will be downloaded from the server
				"initially_open" : [ "node_2" , "node_3" ]
			}
		})
		.bind("create.jstree", function (e, data) {
			$.post(
				"<?php echo $url ?>",
				{
					"operation" : "create_node",
					"id" : data.rslt.parent.attr("id").replace("node_",""),
					"position" : data.rslt.position,
					"title" : data.rslt.name,
					"type" : data.rslt.obj.attr("rel")
				},
				function (r) {
					if(r.status) {
						$(data.rslt.obj).attr("id", "node_" + r.id);
					}
					else {
						$.jstree.rollback(data.rlbk);
					}
				}
			);
		})
		.bind("remove.jstree", function (e, data) {
			data.rslt.obj.each(function () {
				$.ajax({
					async : false,
					type: 'POST',
					url: "<?php echo $url ?>",
					data : {
						"operation" : "remove_node",
						"id" : this.id.replace("node_","")
					},
					success : function (r) {
						if(!r.status) {
							data.inst.refresh();
						}
					}
				});
			});
		})
		.bind("rename.jstree", function (e, data) {
			$.post(
				"<?php echo $url ?>",
				{
					"operation" : "rename_node",
					"id" : data.rslt.obj.attr("id").replace("node_",""),
					"title" : data.rslt.new_name
				},
				function (r) {
					if(!r.status) {
						$.jstree.rollback(data.rlbk);
					}
				}
			);
		})
		.bind("move_node.jstree", function (e, data) {
			data.rslt.o.each(function (i) {
				$.ajax({
					async : false,
					type: 'POST',
					url: "<?php echo $url ?>",
					data : {
						"operation" : "move_node",
						"id" : $(this).attr("id").replace("node_",""),
						"ref" : data.rslt.np.attr("id").replace("node_",""),
						"position" : data.rslt.cp + i,
						"title" : data.rslt.name,
						"copy" : data.rslt.cy ? 1 : 0
					},
					success : function (r) {
						if(!r.status) {
							$.jstree.rollback(data.rlbk);
						}
						else {
							$(data.rslt.oc).attr("id", "node_" + r.id);
							if(data.rslt.cy && $(data.rslt.oc).children("UL").length) {
								data.inst.refresh(data.inst._get_parent(data.rslt.oc));
							}
						}
						$("#analyze").click();
					}
				});
			});
		});
});
</__script>
<__script__ type="text/javascript">
$(function () {
	$(".buttons button").click(function () {
		switch(this.id) {
			case "add_default":
			case "add_category":
				$("#demo").jstree("create", null, "last", { "attr" : { "rel" : this.id.toString().replace("add_", "") } });
				break;
			case "search":
				$("#demo").jstree("search", document.getElementById("text").value);
				break;
                        case "clear_search":
                            $(".buttons #text").attr('value', '');
			case "text": break;
			default:
				$("#demo").jstree(this.id);
				break;
		}
	});
});
</__script>

<!--<div style="position:absolute; right:30px; top:120px; width:220px; border:1px solid silver; min-height:160px;">
	<input type="button" style='display:block; width:170px; height:24px; margin:5px auto;' value="reconstruct" onclick="$.get('./server.php?reconstruct', function () { $('#demo').jstree('refresh',-1); });" />
	<input type="button" style='display:block; width:170px; height:24px; margin:5px auto;' id="analyze" value="analyze" onclick="$('#alog').load('./server.php?analyze');" />
	<input type="button" style='display:block; width:170px; height:24px; margin:5px auto;' value="refresh" onclick="$('#demo').jstree('refresh',-1);" />
	<div id='alog'></div>
</div>-->

<!--<p style="margin:1em 2em 3em 2em; text-align:center; ">If you like the project - consider <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=paypal@vakata.com&currency_code=USD&amount=&return=http://jstree.com/donation&item_name=Buy+me+a+coffee+for+jsTree">supporting jstree</a>.</p>-->

</div>
If you want, I can create user with permissions to this module for you and you can loggin to www.cms.ionic.pl/admin with user vilkis and pass 12345 please try if that's will be helpful... The module is under menu called "Treść" -> "Sklep internetowy"

Re: How to call AJAX from module

Posted: Mon Feb 14, 2011 4:08 pm
by vilkis
I do not need access to admin panel. Your code is a bit complex as you don't use smarty templates. I am not so strong in Ajax to help you further. Sorry.
vilkis