I started with this tutorial http://dojotoolkit.org/documentation/tutorials/1.6/store_driven_tree/
after setting up my ServerSide Restfull Service everything is working so far. I made a contextmenu for the tree by:
<ul dojoType="dijit.Menu" id="contextMenu" style="display: none;">
<li dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconDelete" onclick="pages.remove(tn.item.id);">delete page</li>
</ul>
<script type="dojo/connect">
var menu = dijit.byId("contextMenu");
menu.bindDomNode(this.domNode);
dojo.connect(menu, "_openMyself", this, function(e){
// get a hold of, and log out, the tree node that was the source of this open event
tn = dijit.getEnclosingWidget(e.target);
// contrived condition: disable all menu items except the "New Page" item
dojo.forEach(menu.getChildren(), function(child){
if(child.label != "Neue Seite")
{
child.set('disabled', typeof tn.item == 'undefined');
}
});
});
</script>
Now I know on wich node the user made the right click for the contextmenu and delete it with "pages.remove(tn.item.id);" from the Database. To notify the tree I´m overriding the remove function:
remove: function(objectId){
this.onDelete({id: objectId});
return dojo.store.JsonRest.prototype.remove.apply(this, arguments);
}
Everything works as expected but if im now doing some other things with the items in the tree like drag n drop an item to the root i was deleting a child before. The tree isn't showing it correctly anymore. I think the remove method of the store only sends the DELETE query to the Server but don't removes the item from the store. How can i get the array of the items in store to check and maybe to delete items?
The dijit.Tree is a presentation of an underlying dojo.data model, and any changes that you want to make to the tree really need to be done to the underlying data store. See the description here: http://dojotoolkit.org/reference-guide/dijit/Tree.html#dijit-tree So, instead of overriding the remove function, you should instead use the dojo.data API to modify the store, and then rerender the tree to reflect the changes. The best source for looking at the various methods available is in the dojo nightly files. Specifically, the dojo.data files are here: http://archive.dojotoolkit.org/nightly/dojotoolkit/dojo/data/
var item = tree.fetchItemByIdentity("selectedItem"); //find the item you want to remove
store.deleteItem(item); //delete the item from the data store
store.save(); //save the change made to the store
Related
I'm trying to make a simple extension of the table element. Where you can click a td, then it becomes editable, and when you edit the data it gets automatically persisted via a REST service.
Here's what I got so far
As you can see, you can click the td's and edit them, but the data does not get persisted to the other side (which is firebase in this case). That's because the data in the td's aren't bound anymore to the data-property from which they came. Can somebody tell me how I can bind them to that property again? Or any other way I can persist the data to the correct row and key?
As far as I know contenteditable change events are not supported by polymer.
You could use the onkeys to update the model manually.
In a on-* handler, you can access the named model instance using: e.target.templateInstance.model.:
<polymer-element name="x-foo">
<template>
<template repeat="{{user in users}}">
<div on-click="{{clickHandler}}">{{user.name}}</div>
</template>
</template>
<script>
Polymer('x-foo', {
clickHandler: function(e, detail, sender) {
console.log(sender.templateInstance.model.user.name);
}
});
</script>
</polymer-element>
Sevesta told me that it could only be done manually, so I gave every td extra data-attributes so I could identify them and then at the stopEditing() function I update the models manually.
See here.
im trying to create customizable menu in umbraco. i.e. user should be able to add /remove / edit any menu item in menu. (User will not be a developer)
but i dont know how to do that..i've heard about Macros but dont know much about them so cant use it.
I think this has been done before also..
Thanks in advance
Generally, your menu will reflect your node structure within umbraco. This is the easiest way to allow your clients control of the site's navigation. If there are nodes that you would rather not have in the menu, that you could use the umbracoNaviHide property on the document type.
Try out some of the starter kits that are available. They will come with macros that build the navigation based on your nodes and will give you a good idea of how they work. You can even start by using a starterkit and then just modify it as you like. That's what I would recommend as you start out with umbraco. Umbraco has about 4 or so built in starterkits and Our Umbraco has several more that other users have contributed.
To use the default navigation template provided with Umbraco:
If you log into the Umbraco backoffice and head over to the Developer section, should should see Scripting Files. Right-click Scripting Files and choose Create. Choose a filename, like Nav and and from the "Choose a template" menu, select Site Map, then click Create. You should end up with the following razor code:
#*
SITEMAP
=================================
This snippet generates a complete sitemap of all pages that are published and visible (it'll filter out any
pages with a property named "umbracoNaviHide" that's set to 'true'). It's also a great example on how to make
helper methods in Razor and how to pass values to your '.Where' filters.
How to Customize for re-use (only applies to Macros, not if you insert this snippet directly in a template):
- If you add a Macro Parameter with the alias of "MaxLevelForSitemap" which specifies how deep in the hierarchy to traverse
How it works:
- The first line (var maxLevelForSitemap) assigns default values if none is specified via Macro Parameters
- Next is a helper method 'traverse' which uses recursion to keep making new lists for each level in the sitemap
- Inside the the 'traverse' method there's an example of using a 'Dictionary' to pass the 'maxLevelForSitemap' to
the .Where filter
- Finally the 'traverse' method is called taking the very top node of the website by calling AncesterOrSelf()
NOTE: It is safe to remove this comment (anything between # * * #), the code that generates the list is only the below!
*#
#inherits umbraco.MacroEngines.DynamicNodeContext
#helper traverse(dynamic node){
var maxLevelForSitemap = String.IsNullOrEmpty(Parameter.MaxLevelForSitemap) ? 4 : int.Parse(Parameter.MaxLevelForSitemap);
var values = new Dictionary<string,object>();
values.Add("maxLevelForSitemap", maxLevelForSitemap) ;
var items = node.Children.Where("Visible").Where("Level <= maxLevelForSitemap", values);
if (items.Count() > 0) {
<ul>
#foreach (var item in items) {
<li>
#item.Name
#traverse(item)
</li>
}
</ul>
}
}
<div class="sitemap">
#traverse(#Model.AncestorOrSelf())
</div>
This will produce a ul/li menu of the structure of your site. You plug this into your template by inserting the macro.
Take a look at the default Top Navigation template for XSLT or Razor. That should give you an idea of where to start and how navigation generally works in Umbraco. I second Douglas' answer that the Navigation usually mirrors the content structure in the Content section.
If you really want a setup where you add items to the nav independent of the Content tree structure, then use a Multinode Tree Picker on your Home Page and have that be the navigation in your Top Nav macro.
Here's a simplified example of what I'm trying to achieve: http://jsfiddle.net/easLc/
HTML
<div class="bar">
<div class="apple"> apple</div>
<div class="banana"> banana</div>
<div class="citrus"> citrus </div>
</div>
jQuery
function showAlert(event) {
inventory = event.data.inventory;
alert(inventory);
}
fruits = ["apple", "banana", "citrus"];
inventory = [13, 45, 99];
for (i in fruits) {
$(".bar ."+fruits[i]).on("click", {inventory:inventory[i]},showAlert);
}
The inventory data I'm passing to the handler is dynamic, not static like the example. I'm getting the inventory data from asynchronous calls. After each time the inventory data is updated, I want to pass this data to the handler instead of have the handler get that information again.
What I'm noticing is on some clicks, the handler (I think) is crashing my browser. Am I creating too many handlers inadvertently? How do I see what handlers were created? Or what happens during the click event? I tried adding some console.log to the handler but I don't see them in the console.
Thanks!
Try
$(".bar ."+fruits[i]).off('click',showAlert).on("click", {inventory:inventory[i]},showAlert);
This will remove the previously bound event and rebind it... But it is hard to determine if it is the real source of the problem. You can add a console.log('text') in showAlert to see if it is being called more than once.
You can prevent multiple bindings by adding some sort of data to the element once it's been bound (a clean way would be a class, but meta-data may be preferred by standards):
$(".bar ." + fruits[i]).not(".bound").on('click', {...}).addClass('bound');
I'm using jquery-ui tab example to add extra tabs. I changed that code to be able to add tabs that load a form via Ajax. I was able to create that just changing these:
var $tabs = $( "#tabs").tabs({
cache: true,
tabTemplate: "<li><a href='formularioAgricola.php' id='#{label}'>#{label}</a> <span class='ui-icon ui-icon-close'>Remove Tab</span></li>"
//ajaxOptions: a
});
So I changed the tabTemplate to load the same Form always.
My problem is that I'm not sure how to retrieve, either to tell that every tag from that form use jquery-ui stuff, like buttons, datepickers, etc.
In a regular form I would do something like:
$("#btnRevisar").button()
But when we talk about form load via Ajax it is different.
and also, how can I try to differ one form from other one, if they are all named with the same name, is it possible?
Thanks guys
Carlos.
Within the tabs docs page, tab titled "Events" there is a "load" event. The "ui" argument gives you access to an object that includes the current panel that is loaded. If you are using same ID on forms, beware that ID's must be unique in a page.
var $tabs = $( "#tabs").tabs({
cache: true,
tabTemplate: "<li><a href='formularioAgricola.php' id='#{label}'>#{label}</a> <span class='ui-icon ui-icon-close'>Remove Tab</span></li>",
/* add new option for load event*/
load: function( event, ui){
var $currTabContentPanel=$(ui.panel);
/* only look in currently loaded content for formClass*/
$currTabContentPanel.find('.formClass').doSomething()
}
});
I'm new to ASP.NET MVC 2, and I need some advice on the best 'Control' to use for this situation. (I'm know ASP.NET MVC doesn't really use server controls, but there are a number of add-ons such as MVC Controls ToolKit).
Here's what I need to do. I have a table in a database which contains a list of tests. I need to be able to display these in a View, and allow the user to select them in some way (via checkboxes or whatever).
Then I need to be able to determine which items are selected.
Can someone tell me the best way to achieve this?
Any help/comments are appreciated.
TIA.
If you do it with client side functionality, it will end up consisting mainly of two parts:
The visual HTML
The functional Javascript
How would I'd do it
I'd create a partial view that displays the table. If you need to reuse this, put the partial in Views/Shared folder
Each TR of the table would have serialized JSON of the object that is displayed in that particular row. Serialization can be done by writing a custom object extension method, so you can call ToJson() on any object afterwards
<tr data='<%= this.Model[0].ToJson()'>
<td class="actions"> Select ... </td>
<td>...</td>
...
</tr>
Mind the extra column with actions that you need to provide.
also add a Javascript that would provide the client side functionality (important: this script uses jQuery)
$(function(){
var selection = {};
$(".actions a.action-select").click(function(evt){
evt.preventDefault();
var context = $(this);
var rowObj = $.parseJSON(context.closest("tr[data]").toggleClass("selected").attr("data"));
if (selection[rowObj.Id])
{
// deselect
delete selection[rowObj.Id];
}
else
{
// select
selection[rowObj.Id] = rowObj;
}
});
This way your rows will have additional selected class when they're selected and your selection object will always have selected rows (or better said their objects) taht you can use however you please.
Additional note
Why did I set selection to be an object rather than an array? Because Javascript objects are kind of associative arrays so searching for a particular element is faster than enumerating over its elements it it was a normal array. This way I can immediately see whether row is selected or not and also remove an element from it directly.
Outcome
This way you'll have a reusable table that you can put on various pages (hence similarities with user controls). but in case you'd need to add several of these tables to your pages you'd have to tweak them a little so that client-side functionality won't mix data between different tables.