Adding HTML in a dojo Tree label - javascript

I have a dojo dijit.Tree, and I want to be able to put some html in the labels. To do this, I created an function called getCustomLabel and assigned it to the tree getLabel attribute:
tree = new dijit.Tree({
model: aMOdel,
showRoot: false,
getLabel: getCustomLabel
});
function getCustomLabel(item) {
return '<b>'+item.name+'</b>'
}
This returns a Tree with the html escaped so that it displays in the tree. Does anyone know of a way to get unescaped html in a tree widget?

There is a very simple way actually :)
Right after the dojo.require statement add the following:
dojo.require("dijit.Tree");
dijit._TreeNode.prototype.setLabelNode = function (label) {
this.labelNode.innerHTML = label;
};

With dojo release 1.7.1 the following works:
dojo.require("dijit.Tree");
dijit._TreeNode.prototype._setLabelAttr = {node: "labelNode", type: "innerHTML"};

Wouldn't unescape() achieve this?
function getCustomLabel(item) {
item.name = unescape(item.name);
return '<b>'+item.name+'</b>';
}

you can use onClick event and redirect page to that addess:
<div dojotype="dijit.Tree" model="model" id="tree" >
<script type="dojo/method" event="onClick" args="item,treeNode">
window.location = "/Default.aspx?ItemId=" + dataStore.getIdentity(item);
</script>
</div>

If you just want to print your label in bold, you can redefine getLabelStyle function of your dijit/Tree.
For instance:
getLabelStyle: function(item) {
return {'font-weight': 'bold'};
}

Related

Use ng-class to display some text

Can I use ng-class to display text in addition to a temporary class on my div?
Here's my code.
HTML:
<button ng-click="setBulkMode()"
<div class="filter-nav-bar" ng-class="{'filter-nav-bar-bulk-mode': bulkMode}">
JS:
$scope.setBulkMode = function() {
if(!$scope.bulkMode) {
$scope.bulkMode = true;
} else {
$scope.bulkMode = false;
}
};
Whenever I'm setting bulkMode to true, on my ng-class I'd like to display some text as well. So something like...
<div class="filter-nav-bar" ng-class="{'filter-nav-bar-bulk-mode': bulkMode 'Bulk Mode On'">
But I'm not quite sure how to do that. Any ideas?
Try the following:
<div class="filter-nav-bar" ng-class="{'filter-nav-bar-bulk-mode': bulkMode">
<span ng-show="bulkMode">Bulk Mode On</span>
And you dont need that function to set, you can do this easily in the view:
<button ng-click="bulkMode = !bulkMode">
Separate it. Create a new div with the ng-if directive to show it conditionally:
<div ng-if="bulkMode">Bulk Mode On</div>
And also, you can better write your function (personally I would rename it to toggleBulkMode):
$scope.setBulkMode = function() {
$scope.bulkMode = !$scope.bulkMode;
};

D3 and AngularJS directives

I'm trying to combine AngularJS and D3 -- two awesome libraries. This example is contrived but I have a legitimate use case where I'd like to insert HTML with AngularJS directives by means of D3.
Here's an example with:
a simple AngularJS directive,
a simple adding of content with D3
and finally adding a content with AngularJS directive using D3.
The last one does not work; why?
Here's the Fiddle.
HTML:
<body ng-app="d3">
<div hello></div>
<div hello-d3></div>
<div hello-d3-angular></div>
</body>
JS:
angular.module('d3', [])
.directive('hello', function() {
return {
template: 'Hello Angular!'
};
})
.directive('helloD3', function() {
return {
link: function(scope,elt) {
d3.select(elt[0]).append('div').text('Hello d3!')
}
};
})
.directive('helloD3Angular', function($compile) {
return {
link: function(scope,elt) {
var node = $compile('<div hello></div>')(scope);
d3.select(elt[0]).append(node[0]);
}
};
});
I think it's about D3 API, selection.append(name) .
The name may be specified either as a constant string or as a function that returns the DOM element to append.
http://jsfiddle.net/bateast/4SGsc/7/
So if you want to pass a DOM to .append(), try this instead:
d3.select(elt[0]).append(function() { return node[0]; });
You can solve this using a callback arrow function
d3.select(elt[0]).append(function() {()=> $compile('<div hello></div>')(scope)[0] });

Replacing widget element with a newly constructed DOM structure

<script>
(function( $ ) {
$.widget( "my.dropbox", {
errorText: function(text) {
$(this.element).next().html(text);
},
_create: function() {
var id = $(this.element).attr("id");
var customDropbox = $(
"<div class='form-group'>"+
"<label for='"+id+"'>"+getLabelFor(id)+"</label>"+
"<select id='"+id+"'></select>"+
"<div class='errors'></div>"+
"</div>"
);
customDropbox.attr("id", id);
$(this.element).replaceWith(customDropbox); // This removes original element from DOM
populateOptions(id);
},
});
}( jQuery ));
$(document).ready(function(){
$("#field1").dropbox(); //blank input field turns into a select with a label, populated options e.t.c..
$("#button1").on("click", function(){
$("#field1").dropbox("errorText", "This is a validation error message"); //throws an error saying dropbox is not initialized
});
});
</script>
<html>
<body>
<input id="field1" />
<button id="button1">Press me</button>
</body>
</html>
So I want a widget with public methods that will replace the original element with all the widget data associated with it. The problem with the above code is that the <select..> element is just a DOM element and if you call .dropbox(..) on it, it will say the widget is not initialized. Is there a way to make the select element into the widget object with the .errorText() method? All widget examples online add stuff around the original element but never replace it. As for the bigger picture, I'm trying to make a generic tool to configure forms dynamically. It's going to be all <input id="..."> in html but then javascript will query a database, get configuration for the field and turn it into a dropbox, checkbox or, say, a date picker with all the labels, validation, and other bells and whistles.
There is more than one issue with your widget code. I'll try to summarize them:
1. Copy the data
You're not copying the data to the newly created customDropbox, so before
this.element.replaceWith(customDropbox);
you should copy the data:
customDropbox.data(this.element.data());
Now the widget will remember that it was initialized.
2. this.element is gone
After
this.element.replaceWith(customDropbox);
you should update this.element so that it points to the newly created customDropbox:
this.element = customDropbox;
3. errorText message takes wrong element
Since the widgets element (this.element) is now pointing to the <div class='form-group'></div> element, the errorText function must be slightly modified to:
this.element.find(".errors").html(text);
4. id should be unique
Now, both the wrapper <div> and the <select> have the same id, which is not allowed in HTML so remove the one on the <select> tag. Luckily, <label> can work without the for attribute, just write it like this:
<label>labelForId <select></select></label>
Then to get the <select>-element, use this.element.find("select") in the widget.
Side note
`this.element` is already a jQuery element, so no need for the additional `$()` wrapping.
See this jsFiddle
function show(){
$("#field1").input({....});
}
function hide(){
$("#field1").input("hide");
}
<button onclick="show()">show</button>
<button onclick="hide()">hide</button>
i think to replace the origin element which initial dropbox() is not a good solution,
because this will force you to rely on the implemention details of jQuery ui factory,
it is easy to make a mistake or introduce bugs, sometimes harder for other people to understand your code
if jquery ui factory change the implemention in the future, you have to modify all your code to make it work
(sorry for my limit understand of jquery ui)
i think we can put the <input/> into a container and initial dropbox() on the container which inturn
replace <input/> with <select> datepicker ..etc.. we can build modules easily by doing so:
<form>
<div class="dropbox"><label for="someID">aaaaaa</label><input id="someID"/></div>
<div class="datepicker"></div>
<div class="othermodule"></div>
</form>
js:
$(".dropbox").dropbox(); // init dropbox you defined
$(".datepicker").datepicker(); // ...
$(".othermodule").othermodule(); // ...
$(".dropbox").dropbox("errorText", "error"); // invoke it smoothly
here is a simple demo: http://jsfiddle.net/m4A3D/
#Wouter Huysentruit's answer provides a list of good suggestion for me
<form>
<div class="dropbox">
<label for="someID">aaaaaa</label>
<input id="someID"/>
</div>
<div class="datepicker"></div>
<div class="othermodule"></div>
</form>
<button id="button1">Press me</button>
<script>
(function ($){
$.widget("my.dropbox", {
_create: function () {
var $input = this.element.find("input");
var sID = $input.attr("id");
var $select = $("<select>");
$select.attr("id", sID);
$input.replaceWith($select);
this.element.append("<div class='errors'></div>");
}, // end _create()
errorText: function (text) {
this.element.find(".errors").text(text);
} // end errorText()
});
}(jQuery));
$(".dropbox").dropbox();
$("#button1").click(function () {
$(".dropbox").dropbox("errorText", "this is error");
});
</script>

How to set position for dialog created via JavaScript

HTML:
Link
JavaScript
$(document).ready(function() {
$(document.body).on('click',"a",function(event){
if ($(this).hasClass('ui-dialog-titlebar-close')) return;
event.preventDefault();
var data = '<div id="dialog" title="Basic dialog">';
data += '<p>Hello.</p></div>';
$(data).dialog();
});
});
I want to set a position for this dialog. I've tried changing $(data).dialog(); to $(data).dialog('option', 'position', [200,300]);, but it doesn't work. How can I set it?
jsFiddle: http://jsfiddle.net/fcTcf/
it should be:
$(data).dialog({
position: [200, 300]
});
The syntax $(data).dialog('option', 'option-name', value) is used for changing an option of a dialog that has already been initialized. But if you want to specify options at initialization time, you do so using a option object as the argument to the widget.
There is a link to api documentation for the jQuery Dialog Widget and this jQuery position will help you if you want more granular control of the position.
You're using the selector incorrectly.
$(data) where $data is not a class or id, data is a string containing html.
Try $("#dialog").dialog(); And then you surely would be able to figure it out with the API-documentation.
$(document).ready(function() {
$(document.body).on('click',"a",function(event){
if ($(this).hasClass('ui-dialog-titlebar-close')) return;
event.preventDefault();
var data = '<div id="dialog" title="Basic dialog">';
data += '<p>Hello.</p></div>';
var options={
position:[200,300]
};
$(data).dialog(options);
});
});
You can set 'option' like this

how to get outerHTML with jquery in order to have it cross-browser

I found a response in a jquery forum and they made a function to do this but the result is not the same.
Here is an example that I created for an image button:
var buttonField = $('<input type="image" />');
buttonField.attr('id', 'butonFshi' + lastsel);
buttonField.val('Fshi');
buttonField.attr('src', 'images/square-icon.png');
if (disabled)
buttonField.attr("disabled", "disabled");
buttonField.val('Fshi');
if (onblur !== undefined)
buttonField.focusout(function () { onblur(); });
buttonField.mouseover(function () { ndryshoImazhin(1, lastsel.toString()); });
buttonField.mouseout(function () { ndryshoImazhin(0, lastsel.toString()); });
buttonField.click(function () { fshiClicked(lastsel.toString()); });
And I have this situation:
buttonField[0].outerHTML = `<INPUT id=butonFshi1 value=Fshi src="images/square-icon.png" type=image jQuery15205073038169030395="44">`
instead the outer function I found gives buttonField.outer() = <INPUT id=butonFshi1 value=Fshi src="images/square-icon.png" type=image>
The function is:
$.fn.outer = function(val){
if(val){
$(val).insertBefore(this);
$(this).remove();
}
else{ return $("<div>").append($(this).clone()).html(); }
}
so like this I loose the handlers that I inserted.
Is there anyway to get the outerHTML with jquery in order to have it cross-browser without loosing the handlers ?!
You don't need convert it to text first (which is what disconnects it from the handlers, only DOM nodes and other specific JavaScript objects can have events). Just insert the newly created/modified node directly, e.g.
$('#old-button').after(buttonField).remove();`
after returns the previous jQuery collection so the remove gets rid of the existing element, not the new one.
Try this one:
var html_text = `<INPUT id=butonFshi1 value=Fshi src="images/square-icon.png" type=image jQuery15205073038169030395="44">`
buttonField[0].html(html_text);
:)
Check out the jQuery plugin from https://github.com/darlesson/jquery-outerhtml. With this jQuery plugin you can get the outerHTML from the first matched element, replace a set of elements and manipulate the result in a callback function.
Consider the following HTML:
<span>My example</span>
Consider the following call:
var span = $("span").outerHTML();
The variable span is equal <span>My example</span>.
In the link above you can find more example in how to use .outerHTML() plug-in.
This should work fine:
var outer = buttonField.parent().html();

Categories

Resources