I am new to angularjs and I would like to understand what the directives do but I can't find a tutorial with different example by complexity and I was curios if I could move the following code in a directive.
This is my javascript file(controller.js):
function TestCtrl(){
var json = {
id:"judge_id",
name:"Test",
children: [ {
id:"filter_1",
name:'Filter 1',
children:[{id:"case_1",name:"CaseA",children:[]},{id:"case_2",name:"CaseB",children:[]},{id:"case_3",name:"CaseC",children:[]}]
},
{
id:"filter_2",
name:'Filter 2',
children:[]
},
{
id:"filter_3",
name:'Filter 3',
children:[]
},
{
id:"filter_4",
name:'Filter 4',
children:[]
},
{
id:"filter_5",
name:'Filter 5',
children:[]
},
{
id:"filter_6",
name:'Filter 6',
children:[]
}
]
};
var rgraph = new $jit.RGraph({
//Where to append the visualization
injectInto: 'infovis',
background: {
CanvasStyles: {
strokeStyle: '#555'
}
},
//Add navigation capabilities:
//zooming by scrolling and panning.
Navigation: {
enable: true,
panning: true,
zooming: 10
},
//Set Node and Edge styles.
Node: {
color: '#ddeeff'
},
Edge: {
color: '#C17878',
lineWidth:1.5
},
//Add the name of the node in the correponding label
//and a click handler to move the graph.
//This method is called once, on label creation.
onCreateLabel: function(domElement, node){
domElement.innerHTML = node.name;
domElement.onclick = function(){
rgraph.onClick(node.id, {
onComplete: function() {
Log.write("done");
}
});
};
},
//Change some label dom properties.
//This method is called each time a label is plotted.
onPlaceLabel: function(domElement, node){
var style = domElement.style;
style.display = '';
style.cursor = 'pointer';
if (node._depth <= 1) {
style.fontSize = "0.8em";
style.color = "#ccc";
} else if(node._depth == 2){
style.fontSize = "0.7em";
style.color = "#494949";
} else {
style.display = 'none';
}
var left = parseInt(style.left);
var w = domElement.offsetWidth;
style.left = (left - w / 2) + 'px';
}
});
//load JSON data
rgraph.loadJSON(json);
//trigger small animation
rgraph.graph.eachNode(function(n) {
var pos = n.getPos();
pos.setc(-200, -200);
});
rgraph.compute('end');
rgraph.fx.animate({
modes:['polar'],
duration: 2000
});
}
ANd my html file is like this:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="http://philogb.github.io/jit/static/v20/Jit/jit-yc.js"></script>
<script src="..js/controller.js"></script>
<link type="text/css" href="../base.css" rel="stylesheet" />
<title></title>
</head>
<body onload="TestCtrl();">
<div id="center-container">
<div id="infovis"></div>
</div>
</body>
</html>
Thanks
Sabbu
Related
I added a yandex.metrica script (w ecommerce layer) in my index.html
<!-- Yandex.Metrika counter -->
<script type="text/javascript" >
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
ym(id, "init", {
clickmap:true,
trackLinks:true,
accurateTrackBounce:true,
webvisor:true,
ecommerce: "dataLayer"
});
</script>
<!-- /Yandex.Metrika counter -->
I need to send some data-objects to ecommerce layer like this dataLayer.push({ ecommerce: "someData" }), but i dont understand how to do it correctly inside a react component...
it should work just like other events for YM
window.ym(yaCounterId, "reachGoal", eventName)
window.dataLayer.push({
ecommerce: {
currencyCode: 'RUB',
add: {
products: [
{
id: '43521',
name: 'Yandex bag',
price: 654.32,
brand: 'Yandex / Яndex',
category: 'Accessories/Bags',
quantity: 1,
},
],
},
},
});
just create wrapper function to make it look better
We have a web application that is built using JSP pages. We are trying to migrate UI to React. Migration needs to be incremental as it's a huge application and we cannot migrate it completely in one go.
We are trying to run a poc to see how we will integrate react components in phased manner. We are able to integrate a vanilla react component (a static Select) following this React Docs page.
Problem comes when we started using useState hook. We started to get "Invalid Hook Call Warning".
We created a react app and created components there, it works as react application. We converted JSX components to plain JS using Babel cli (steps as mentioned on the React Doc Page).
Next we loaded React and React-DOM in the application through script tag as suggested on the page, except that we downloaded the script and referred from the file system.
<script src="https://unpkg.com/react#18/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#18/umd/react-dom.production.min.js" crossorigin></script>
<script type="text/javascript" src="<path to component JS>"></script>
When we tried to load the Select component in the target DIV element, we got the hook warning.
I extracted code into a sample html
<html>
<head>
<title>My Page</title>
</head>
<body>
<h1>Try React</h1>
<div id="targetDiv">
<h5>Place content here</h5>
</div>
<script type="text/javascript" src="./react/react.development.js"></script>
<script type="text/javascript" src="./react/react-dom.development.js"></script>
<script type="text/javascript" src="./react/components/core/coreSelect.js"></script>
<script type="text/javascript">
function getSelectOptions() {
const options = [];
options.push({ text: "Select...", value: "" });
options.push({ text: "Arizona", value: "AZ" });
options.push({ text: "Canada", value: "CA" });
options.push({ text: "Europe", value: "EU" });
options.push({ text: "Hawai", value: "HW" });
options.push({ text: "Mexico", value: "MX" });
options.push({ text: "New York", value: "NY" });
return options;
};
let selectArgs = {id:"mySelect", name: "mySelect", options: getSelectOptions(), value: "CA"};
let root = document.getElementById('targetDiv');
console.log({root});
ReactDOM.createRoot(root).render(Select(selectArgs));
</script>
</body>
</html>
Following is the content of coreSelect.js
var _slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i)
break;
}
} catch (err) {
_d = true; _e = err;
} finally {
try {
if (!_n && _i["return"])
_i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) { return arr; }
else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); }
else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
};
}();
function Select(_ref4) {
var id = _ref4.id,
name = _ref4.name,
value = _ref4.value,
options = _ref4.options;
var optArray = options ? options : [{ text: 'Select', value: '' }];
console.log("Before useState7", {useState});
var _useState7 = React.useState(options ? options : [{ text: 'Select', value: '' }]),
_useState8 = _slicedToArray(_useState7, 2),
optArray = _useState8[0],
setOptArray = _useState8[1];
console.log("Before useState9");
var _useState9 = React.useState(value),
_useState10 = _slicedToArray(_useState9, 2),
selectedVal = _useState10[0],
setSelectedVal = _useState10[1];
console.log("Before useState11");
var _useState11 = React.useState(""),
_useState12 = _slicedToArray(_useState11, 2),
effectiveClasses = _useState12[0],
setEffectiveClasses = _useState12[1];
var disabled = options && options.length > 0 ? false : true;
var onFocusClass = "active";
function processOnClick() {
if (!effectiveClasses || effectiveClasses.search(onFocusClass) < 0) {
setEffectiveClasses(function (prevClasses) {
var newClasses = (prevClasses ? prevClasses.trim() + " " : "") + onFocusClass;
return newClasses;
});
} else {
setEffectiveClasses(function (prevClasses) {
var newClasses = prevClasses.replace(onFocusClass).trim();
return newClasses;
});
}
}
return React.createElement(
"select",
// { id: id, name: name, className: "active", defaultValue: value, onClick: processOnClick, disabled: disabled },
{ id: id, name: name, className: effectiveClasses, defaultValue: selectedVal, onClick: processOnClick, disabled: disabled },
optArray && optArray.map(function (opt) {
var optValue = opt.value;
var optText = opt.text;
return React.createElement(
"option",
{ key: optValue, value: optValue },
optText
);
})
);
};
I have modified the JS file as generated from babel cli to not use imports/exports. I have verified on browser console that React, ReactDOM and Select component are available.
As an experiment I tried to run the command
ReactDOM.createRoot(document.getElementById('targetDiv')).render(Select({id:"mySelect", name: "mySelect", options: getSelectOptions(), value: "CA"}));
from browser console and I still got the react hook error.
I have been trying to search internet to find a solution but all available posts work with npm and try to resolve issues with react version mismatch, but I could not find any that would discuss problem with react integration with existing non-react applications.
Any help in this regard would be greatly appreciated.
I am using KendoUI and angular to implement a very similar scenario as in this example from Telerik website.
http://dojo.telerik.com/AreTa/2
This is what I have
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.common.min.css"/>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.rtl.min.css"/>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.silver.min.css"/>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.mobile.all.min.css"/>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/kendo.all.min.js"></script>
</head>
<body>
<style>html { font: 12px sans-serif; }</style>
<div id="grid"></div>
<script>
var sampleData = [
{ProductName: "Sample Name", Description: "Sample Description"}
];
// custom logic start
var sampleDataNextID = sampleData.length + 1;
function getIndexByName(name) {
var idx,
l = sampleData.length;
for (var j=0; j < l; j++) {
if (sampleData[j].getIndexById == name) {
return j;
}
}
return null;
}
// custom logic end
$(document).ready(function () {
var dataSource = new kendo.data.DataSource({
transport: {
read: function (e) {
// on success
e.success(sampleData);
// on failure
//e.error("XHR response", "status code", "error message");
},
create: function (e) {
// assign an ID to the new item
//e.data.ProductName = e.data;
// save data item to the original datasource
sampleData.push(e.data);
// on success
e.success(e.data);
// on failure
//e.error("XHR response", "status code", "error message");
},
update: function (e) {
// locate item in original datasource and update it
sampleData[getIndexByName(e.data.ProductName)] = e.data;
// on success
e.success();
// on failure
//e.error("XHR response", "status code", "error message");
},
destroy: function (e) {
// locate item in original datasource and remove it
sampleData.splice(getIndexByName(e.data.ProductName), 1);
alert("Delete Success"+e.data.ProductName) ;
// on success
e.success();
// on failure
//e.error("XHR response", "status code", "error message");
}
},
error: function (e) {
// handle data operation error
alert("Status: " + e.status + "; Error message: " + e.errorThrown);
},
pageSize: 10,
batch: false,
schema: {
model: {
id: "ProductName",
fields: {
ProductName: { validation: { required: true } },
Description: { type: "text"}
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
toolbar: ["create"],
columns: [
{ field: "ProductName", title: "Mobile Phone" },
{ field: "Description", width: "120px" },
{ command: ["destroy"], title: "Action;", width: "200px" }
],
editable: "inline"
});
});
</script>
</body>
</html>
And it works, the way it is on Telerik website
The change I want to do is that upon "create", I want the ProductName field be a drop down, instead of textfield, populated with values I have in another json (not sampleData). That has a value (productName) and Description - description
Also, the Description field is not to be typeable, but rather "obtained" from the description of the selected in dropdown.
Can anyone help ?
Use a custom editor for the ProductName field:
http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#configuration-columns.editor
http://demos.telerik.com/kendo-ui/grid/editing-custom
Attach a change handler to the DropDownList and set() the corresponding value to the Description field of the data item (which is a Kendo UI Model instance that you already have from the editor function's arguments).
http://docs.telerik.com/kendo-ui/api/javascript/ui/dropdownlist#events-change
http://docs.telerik.com/kendo-ui/api/javascript/data/observableobject#methods-set
You will also need to prevent direct editing of the Description field. This can be easily achieved if you use a custom "editor" for this field, which simply outputs the current value in a <span> element.
My objective is to have a map to which I can add markers/polygons/... These elements will be saved into an Object for saving. The drawn elements can later be edited/deleted or added to.
I have successfully managed to create/edit/delete them, but when I init my map with the saved objects they can't be edited again.
Working fiddle : http://jsfiddle.net/4fq6m3dc/1/
My code :
leafletData.getMap().then(function (map) {
var drawnItems = $scope.controls.edit.featureGroup;
// Init the map with the saved elements
for (var i = 0; i < $scope.savedItems.length; i++) {
layer = new L.GeoJSON($scope.savedItems[i].geoJSON);
drawnItems.addLayer(layer);
}
map.on('draw:created', function (e) {
var layer = e.layer;
drawnItems.addLayer(layer);
$scope.savedItems.push({
id: layer._leaflet_id,
geoJSON: layer.toGeoJSON()
});
});
map.on('draw:edited', function (e) {
var layers = e.layers;
layers.eachLayer(function (layer) {
for (var i = 0; i < $scope.savedItems.length; i++) {
if ($scope.savedItems[i].id == layer._leaflet_id) {
$scope.savedItems[i].geoJSON = layer.toGeoJSON();
}
}
});
});
map.on('draw:deleted', function (e) {
var layers = e.layers;
layers.eachLayer(function (layer) {
for (var i = 0; i < $scope.savedItems.length; i++) {
if ($scope.savedItems[i].id == layer._leaflet_id) {
$scope.savedItems.splice(i, 1);
}
}
});
});
});
I modified your code and it seems that I have fixed the bugs for you. Here is my code.
<!DOCTYPE html>
<html ng-app="demoapp">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="http://tombatossals.github.io/angular-leaflet-directive/bower_components/angular/angular.min.js"></script>
<script src="http://tombatossals.github.io/angular-leaflet-directive/bower_components/leaflet/dist/leaflet.js"></script>
<script src="http://tombatossals.github.io/angular-leaflet-directive/dist/angular-leaflet-directive.min.js"></script>
<script src="http://tombatossals.github.io/angular-leaflet-directive/bower_components/leaflet.draw/dist/leaflet.draw.js"></script>
<link rel="stylesheet" href="http://tombatossals.github.io/angular-leaflet-directive/bower_components/leaflet/dist/leaflet.css" />
<link rel="stylesheet" href="http://tombatossals.github.io/angular-leaflet-directive/bower_components/leaflet.draw/dist/leaflet.draw.css" />
<script>
var app = angular.module("demoapp", ["leaflet-directive"]);
app.controller("ControlsDrawController", ["$scope", "leafletData", function($scope, leafletData) {
$scope.savedItems = [{
"id": 721,
"geoJSON": {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-0.626220703125,
48.1367666796927
]
}
}
}, {
"id": 724,
"geoJSON": {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-0.274658203125,
49.13859653703879
]
}
}
}, {
"id": 725,
"geoJSON": {"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-18.10546875,53.38332836757156],[-10.107421874999998,55.92458580482951],[-3.33984375,53.9560855309879],[-10.634765625,47.635783590864854],[-17.2265625,45.767522962149904],[-18.10546875,53.38332836757156]]]}}
}];
var drawnItems = new L.FeatureGroup();
for (var i = 0; i < $scope.savedItems.length; i++) {
L.geoJson($scope.savedItems[i].geoJSON, {
style: function(feature) {
return {
color: '#bada55'
};
},
onEachFeature: function (feature, layer) {
drawnItems.addLayer(layer);
}
});
}
angular.extend($scope, {
london: {
lat: 51.505,
lng: -0.09,
zoom: 4
},
controls: {
draw: {},
edit: {
featureGroup: drawnItems
}
}
});
leafletData.getMap().then(function(map) {
var drawnItems = $scope.controls.edit.featureGroup;
// Init the map with the saved elements
var printLayers = function () {
console.log("After: ");
map.eachLayer(function(layer) {
console.log(layer);
});
};
drawnItems.addTo(map);
printLayers();
map.on('draw:created', function(e) {
var layer = e.layer;
drawnItems.addLayer(layer);
console.log(JSON.stringify(layer.toGeoJSON()));
$scope.savedItems.push({
id: layer._leaflet_id,
geoJSON: layer.toGeoJSON()
});
});
map.on('draw:edited', function(e) {
var layers = e.layers;
layers.eachLayer(function(layer) {
for (var i = 0; i < $scope.savedItems.length; i++) {
if ($scope.savedItems[i].id == layer._leaflet_id) {
$scope.savedItems[i].geoJSON = layer.toGeoJSON();
}
}
});
});
map.on('draw:deleted', function(e) {
var layers = e.layers;
layers.eachLayer(function(layer) {
for (var i = 0; i < $scope.savedItems.length; i++) {
if ($scope.savedItems[i].id == layer._leaflet_id) {
$scope.savedItems.splice(i, 1);
}
}
});
});
});
}]);
</script>
<style>
input {
width: 120px;
margin-right: 10px;
}
</style>
</head>
<body ng-controller="ControlsDrawController">
<leaflet center="london" controls="controls" width="100%" height="400"></leaflet>
<h1>Draw control example</h1>
<p>Draw a shape and a geoJSON data structure will be shown on the console.log.</p>
</body>
</html>
http://jsfiddle.net/4fq6m3dc/3/
How can I horizontally expand a combobox pull-down display?
My actual data is: ARAMEX1234
But the pull-down display only shows: ARAMEX123
I need to support the following browsers: IE 6, 7, 8.
I tested it using Firefox and it works out of the box. However, my application will be run on IE and never on FF.
Here is the code (jsp file content):
<%# page pageEncoding="UTF-8" contentType="text/html;charset=UTF-8"%>
<script type="text/javascript" src="<c:url value="/js/jquery/grid.locale-ja.js" />" charset="UTF-8"></script>
<link type="text/css" rel="stylesheet" href="<c:url value="/css/jquery/ui.jqgrid.css" />"/>
<script src="<c:url value="/js/jquery/jquery.jqGrid.min.js" />" type="text/javascript"></script>
<table id="rowed5"></table>
<script type="text/javascript" charset="utf-8">
var lastsel2;
$("#rowed5").jqGrid({
datatype: "local",
height: 250,
colNames:['ID Number','Name', 'Stock', 'Ship via','Notes'],
colModel:[
{name:'id',index:'id', width:90, sorttype:"int", editable: true},
{name:'name',index:'name', width:150,editable: true,editoptions:{size:"20",maxlength:"30"}},
{name:'stock',index:'stock', width:60, editable: true,edittype:"checkbox",editoptions: {value:"Yes:No"}},
{name:'ship',index:'ship', width:90, editable: true,edittype:"select",editoptions:{value:"FE:FedEx;IN:InTime;TN:TNT;AR:ARAMEX;AR1:ARAMEX123456789"}},
{name:'note',index:'note', width:200, sortable:false,editable: true,edittype:"textarea", editoptions:{rows:"2",cols:"10"}}
],
caption: "Input Types",
resizeStop: function (newwidth, index) {
var selectedRowId = $("#rowed5").getGridParam('selrow');
if(selectedRowId) {
//resize combobox proportionate to column size
var selectElement = $('[id="' + selectedRowId + '_ship"][role="select"]');
if(selectElement.length > 0){
$(selectElement).width(newwidth);
}
}
}
,
onSelectRow: function(id){
if(id && id!==lastsel2){
//$(this).saveRow(lastsel2, true);
$(this).restoreRow(lastsel2);
$(this).editRow(id,true);
lastsel2=id;
$(this).scroll();
//resize combobox proportionate to column size
var rowSelectElements = $('[id^="' + id + '_"][role="select"]');
if(rowSelectElements.length > 0) {
$(rowSelectElements).each(function(index, element){
var name = $(element).attr('name');
var columnElement = $('#rowed5_' + name);
if(columnElement.length > 0) {
var columnWidth = $(columnElement).width();
$(element).width(columnWidth);
}
});
}
}
}
});
var mydata2 = [
{id:"12345",name:"Desktop Computer",note:"note",stock:"Yes",ship:"FedEx"},
{id:"23456",name:"Laptop",note:"Long text ",stock:"Yes",ship:"InTime"},
{id:"34567",name:"LCD Monitor",note:"note3",stock:"Yes",ship:"TNT"},
{id:"45678",name:"Speakers",note:"note",stock:"No",ship:"ARAMEX123456789"},
{id:"56789",name:"Laser Printer",note:"note2",stock:"Yes",ship:"FedEx"},
{id:"67890",name:"Play Station",note:"note3",stock:"No", ship:"FedEx"},
{id:"76543",name:"Mobile Telephone",note:"note",stock:"Yes",ship:"ARAMEX"},
{id:"87654",name:"Server",note:"note2",stock:"Yes",ship:"TNT"},
{id:"98765",name:"Matrix Printer",note:"note3",stock:"No", ship:"FedEx"}
];
for(var i=0;i < mydata2.length;i++) {
$("#rowed5").jqGrid('addRowData',mydata2[i].id,mydata2[i]);
}
</script>
This is a well-known bug in IE. You can fix it by temporarily resizing the select input on mouseover or on focus as described in the following article: Select Cuts Off Options In IE (Fix)
In your specific example, the code might look like this:
$("#rowed5 select").live({
focus: function () {
$(this).
data("origWidth", $(this).css("width")).
css("width", "auto");
},
blur: function () {
var $this = $(this);
$this.css("width", $this.data("origWidth"));
}
});