I have a JSC3D scene that contains multiple files. My goal would be to show/hide one of the models with an onClick call.
The two options I can come up with are to recreate the scene with the one model missing, or to somehow access a visible property of one of the models.
I've tried various permutations of the alert code to access the visible property, but no luck there. The updateview function was my attempt to recreate the scene with the missing model. BTW, if you change colors[newLoaded] to colors[newLoaded+1] the colors will update, but the displayed models remain the same.
It has been many years since I looked into this stuff so I am sure it is something easy that I am missing
Thanks
<!DOCTYPE HTML>
<HTML>
<HEAD>
<TITLE>Crown Study Ranking</TITLE>
<script type="text/javascript" src="jsc3d/jsc3d.js"></script>
<script type="text/javascript" src="jsc3d/jsc3d.webgl.js"></script>
<script type="text/javascript" src="jsc3d/jsc3d.touch.js"></script>
</HEAD>
<BODY>
<div style="width:800px; margin:auto; position:relative;">
<canvas id="cv" style="border: 1px solid;" width="750" height="400">
It seems you are using an outdated browser that does not support canvas :-(
</canvas>
<form action="">
<input type="checkbox" name="antagonist" value="1" onClick="this.value = -1*this.value; updateview(this.name,this.value);" checked> Antagonist</input>
<input type="checkbox" name="arch" value="1" onClick="this.value = -1*this.value; updateview(this.name,this.value);" checked> Main Arch</input>
<input type="checkbox" name="crown" value="1" onClick="this.value = -1*this.value; updateview(this.name,this.value);" checked> Crown</input>
</form>
</div>
<script type="text/javascript">
var canvas = document.getElementById('cv');
var viewer = new JSC3D.Viewer(canvas);
var components = ['models/dummy.stl', 'models/dummya.stl', 'models/dummyc.stl'];
var colors = [0xff0000, 0x0000ff, 0x00ff00, 0xffff00, 0x00ffff];
var theScene = new JSC3D.Scene;
var numOfLoaded = 0;
var onModelLoaded = function(scene) {
var meshes = scene.getChildren();
for (var i=0; i<meshes.length; i++) {
theScene.addChild(meshes[i]);
if (meshes.length > 0)
meshes[0].setMaterial(new JSC3D.Material('red-material', 0, colors[numOfLoaded]));
}
if (++numOfLoaded == components.length)
viewer.replaceScene(theScene);
};
for (var i=0; i<components.length; i++) {
var loader = new JSC3D.StlLoader;
loader.onload = onModelLoaded;
loader.loadFromUrl(components[i]);
}
viewer.setParameter('ModelColor', '#FF0000');
viewer.setParameter('BackgroundColor1', '#E5D7BA');
viewer.setParameter('BackgroundColor2', '#383840');
viewer.setParameter('RenderMode', 'flat');
viewer.setParameter('Renderer', 'webgl');
viewer.init();
viewer.update();
alert (meshes[1].visible.value);
//////////////////////////////////////////////////////////////////////////////////////
function updateview (name,value) {
var newScene = new JSC3D.Scene;
var newLoaded = 0;
var newModelLoaded = function(scene) {
var newMeshes = scene.getChildren();
for (var i=1; i<newMeshes.length; i++) {
newScene.addChild(newMeshes[i]);
if (newMeshes.length > 0)
newMeshes[0].setMaterial(new JSC3D.Material('red-material', 0, colors[newLoaded]));
}
if (++newLoaded == components.length)
viewer.replaceScene(newScene);
};
for (var i=1; i<components.length; i++) {
var newloader = new JSC3D.StlLoader;
newloader.onload = newModelLoaded;
newloader.loadFromUrl(components[i]);
}
viewer.update();
};
</script>
</BODY>
</HTML>
1) Add a <div> inside <body> tag say "objectlist".
<div id="objectlist"></div>
2) After the last viewer.update(); add this little code
viewer.onloadingcomplete = function() {
var shtml ="";
for(obj in viewer.scene.children) {
shtml+="<input type='checkbox' value='" + obj + "' checked onclick='setobject(this);'/>" + viewer.scene.children[object] + "<br />";
var objects = document.getElementById(objectlist);
objects.innerHTML = shtml;
};
3) Now add the setobject() function.
function setobject(self) {
viewer.scene.children[self.value].visible = self.checked;
}
Except point #1 everything should be in javascript code.
That's It...
Enjoy and in case any issues let me know # sarillaprasad#yahoo.com [or] post it here :D
Related
I have a table generated from a textarea filled by users, but some of the time, a cell stays empty (and that's all right).
The thing is that the .innerHTML of that cell is also my var y in a script and when that cell is empty (therefore, undefined), my var y becomes UNDEFINED too (the value, not a string), which makes my whole script fail.
Here's a snippet to show the problem:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body><center>
</center></body>
<!--------- script that generates my table from text areas -->
<script>
function generateTable() {
$('#excel_table1').html("");
var n=1;
var rows=[];
var lng=0;
var maxligne=0;
$('textarea').each(function(){
var data = $(this).val();
if (data !=''){
var rowData = data.split("\n");
rows[n] = rowData;
lng = rowData.length;
if(lng > maxligne)
{
maxligne=lng
}
n++;
}
}
)
var table = $('<table />');
k=0;
while (k < maxligne) {
var row = $('<tr />');
for(var i = 1; i < rows.length; i++)
{
var singleRow = rows[i];
if(singleRow[k]!= undefined){
row.append('<td>'+singleRow[k]+'</td>')
} else {
row.append('<td></td>')
}
}
table.append(row);
k++;
}
$('#excel_table1').append(table);
}
</script>
<textarea placeholder="data 2 Here" name="data1" style="width:100px;height:40px;"></textarea>
<textarea placeholder="data 2 Here" name="data2" style="width:200px;height:40px;"></textarea>
<textarea placeholder="fild not required" name="data3" style="width:200px;height:40px;"></textarea>
<br>
<input id=bouton1 type="button" onclick="javascript:generateTable()" value="GenerateTable"/>
<div id="excel_table1"></div>
<!--------- script that get the data from cells to show it in <H2> -->
<script type="text/javascript">
function buttonTEST()
{
$('#displayCell').html("");
var x = document.getElementById('excel_table1').getElementsByTagName('tr')[0].cells[1].innerHTML;
var y = document.getElementById('excel_table1').getElementsByTagName('tr')[0].cells[2].innerHTML;
if (y === undefined) {
y = " ";
}
document.getElementById('displayCell').innerHTML = x +" "+ y;
}
</script>
<br/><br/>
<h2 id="displayCell"></h2>
<br/><br/>
<input id="Button2" type="button" onclick="buttonTEST()" value="TEST ME"/>
As you can see, if you generate a table with only to columns (which is supposed/needs to happen sometimes), we get this error from the console because we're trying to get "innerHTML" from a undefined:
index.html:120 Uncaught TypeError: Cannot read property 'innerHTML' of undefined
A little specification: When that cell is=undefined , I need it to stay undefined, I only want to change the fact that my var y also becomes undefined.
So I thought that changing the value of var y (and not the value of that cell, otherwise, the 3rd column, supposed to be empty, would be created just because of an blank space) to a blank space would resolve the problem, but I don't seem to get it right (write it in a correct manner).
Any ideas?
Try
var x = document.getElementById('excel_table1').rows[0].cells[0].innerHTML;
var y = document.getElementById('excel_table1').rows[0].cells[1].innerHTML;
using rows instead of getElementsByTagName is cleaner.
Also note that the indexes for cells start from zero not 1, you probably only have 2 cells in your first row, but .cells[2].innerHTML tries to get the innerHTML of the 3rd cell which does not exist.
As others have pointed out, you're already using jQuery, so the easiest way to get the cell contents is to use a css selector to find the cells using the $ function, then call .html() to get the contents. A direct conversion of your current code to this approach could be:
var x = $('#excel_table1 tr:nth-child(1) td:nth-child(2)').html();
var y = $('#excel_table1 tr:nth-child(1) td:nth-child(3)').html();
This works in a way so that the $ function returns a jQuery object, which is essentially a set of elements, which can potentially be empty. Most jQuery functions are then designed to fail gracefully when called on an empty set. For instance, html will return undefined when invoked on an empty set, but it will not fail.
Note that it is not very robust to use the selector above, as it is obviously sensitive to the placement of the cells. It would be more maintainable to assign a class attribute to the cells that describes their content, and then select on that, e.g. something like
var name = $("#excel_table1 tr:nth-child(1) td.name").html()
So here's the answer that worked for me:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body><center>
</center></body>
<!--------- script that generates my table from text areas -->
<script>
function generateTable() {
$('#excel_table1').html("");
var n=1;
var rows=[];
var lng=0;
var maxligne=0;
$('textarea').each(function(){
var data = $(this).val();
if (data !=''){
var rowData = data.split("\n");
rows[n] = rowData;
lng = rowData.length;
if(lng > maxligne)
{
maxligne=lng
}
n++;
}
}
)
var table = $('<table />');
k=0;
while (k < maxligne) {
var row = $('<tr />');
for(var i = 1; i < rows.length; i++)
{
var singleRow = rows[i];
if(singleRow[k]!= undefined){
row.append('<td>'+singleRow[k]+'</td>')
} else {
row.append('<td></td>')
}
}
table.append(row);
k++;
}
$('#excel_table1').append(table);
}
</script>
<textarea placeholder="data 2 Here" name="data1" style="width:100px;height:40px;"></textarea>
<textarea placeholder="data 2 Here" name="data2" style="width:200px;height:40px;"></textarea>
<textarea placeholder="fild not required" name="data3" style="width:200px;height:40px;"></textarea>
<br>
<input id=bouton1 type="button" onclick="javascript:generateTable()" value="GenerateTable"/>
<div id="excel_table1"></div>
<!--------- script that get the data from cells to show it in <H2> -->
<script type="text/javascript">
function buttonTEST()
{
$('#displayCell').html("");
var x = $('#excel_table1 tr:nth-child(1) td:nth-child(2)').html();
var y = $('#excel_table1 tr:nth-child(1) td:nth-child(3)').html();
if (y ===undefined)
{document.getElementById('displayCell').innerHTML = x ;}
else
{document.getElementById('displayCell').innerHTML = x +" "+ y;}
}
</script>
<br/><br/>
<h2 id="displayCell"></h2>
<br/><br/>
<input id="Button2" type="button" onclick="buttonTEST()" value="TEST ME"/>
I am trying to add direction to a line overlay i have added to map using openlayers. I have created map and line overlay inside my jsp but the problem is that when ${variable} is used in html file, I am getting output as expected with correct direction shown. But when implemented inside jsp all arrows seem to b pointing to just one direction.
I think the problem is that ${variable} in javascript not substituted in jsp.
Here is the piece of code.
direction.jsp
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Line Direction Arrow in OpenLayers</title>
<link rel="stylesheet" href="http://openlayers.org/dev/theme/default/style.css" type="text/css" />
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
<link rel="stylesheet" href="style.css" type="text/css">
<style type="text/css">
#map {
width: 600px;
height: 400px;
border: 1px solid #ccc;
}
</style>
<script src="js-libraries/OpenLayers.js" type="text/javascript"></script>
<script src="js-libraries/directions.js" type="text/javascript"></script>
<script type="text/javascript">
var map = null;
var myNetwork =null;
function init(){
map = new OpenLayers.Map('map');
var ol_osm = new OpenLayers.Layer.OSM("Simple OSM Map");
map.addLayers([ol_osm]);
//vector layer
var layer = new OpenLayers.Layer.Vector("Line");
map.addLayer(layer);
// add edit panel
var editPanel = new OpenLayers.Control.EditingToolbar(layer);
map.addControl(editPanel);
//add direction layer
OpenLayers.Renderer.symbol.arrow = [0,2, 1,0, 2,2, 1,0, 0,2];
var styleMap = new OpenLayers.StyleMap(OpenLayers.Util.applyDefaults(
{graphicName:"arrow",rotation : "${angle}"},
OpenLayers.Feature.Vector.style["default"]));
var dirLayer = new OpenLayers.Layer.Vector("direction", {styleMap: styleMap});
map.addLayer(dirLayer);
map.setCenter(new OpenLayers.LonLat(-702335,7043201),15);
//console.log("Starting map");
}
function updateDirection() {
//alert(map.layers[2].name);
map.layers[2].removeAllFeatures();
var points=[];
var features =map.layers[1].features;
//alert(features.length);
for (var i=0;i<features.length ;i++ ) {
var linePoints = createDirection(features[i].geometry,get_position_value(),get_foreachseg_value()) ;
//alert(get_foreachseg_value());
// for (var j=0;j<linePoints.length ;j++ ) {
// linePoints[j].attributes.lineFid = features[i].fid;
// }
points =points.concat(linePoints);
// alert(points);
}
map.layers[2].addFeatures(points);
}
function get_position_value() {
for (var i=0; i < document.direction.position.length; i++)
{
if (document.direction.position[i].checked)
{
return document.direction.position[i].value;
}
}
}
function get_foreachseg_value() {
if (document.direction.foreachseg.checked){
return true;
} else {
return false;
}
}
</script>
</head>
<body onload="init()">
<table><tr>
<td><div id="map" class="smallmap"></div></td>
<td><div align="left">
<form name="direction">
<input type="radio" name="position" value="start"/> start <br>
<input type="radio" name="position" value="end"/> end <br>
<input type="radio" name="position" value="middle" CHECKED/>middle <br>
<input type="checkbox" name="foreachseg" /> Create for each segment of line <br>
<input type=button value="Update" onClick=updateDirection(); />
</form>
</div></td>
</tr></table>
</body>
</html>
Is there anyway to get the corresponding angle in jsp? the page seems to b working fine when the file was renamed direction.html But when renamed as direction.jsp the angle value is not received correctly. I need to use this with my jsp application. please help.
Thanks and Regards
Ginger.
As JSP is server side and javascript is client side so you can't pass parameters like this, an alternate would be to add angle as hidden field in your jsp
<input type="hidden" value="angle_value_comes_here" id="angle"/>
and then access it in javascript using
var angle = $('#angle').val();
Hope it helps
I am posting my updated code in here.
function updateDirection() {
flagMarkerStatus = 5;
var angles = 0;
dirLayer.removeAllFeatures();
var linePoints=[];
var points=[];
var features =lineLayer.features;
document.getElementById("angle").value="";
for (var i=0;i<features.length ;i++ ) {
var linePoints = createDirection(features[i].geometry,"middle",true);
points =points.concat(linePoints);
angles = document.getElementById("angle").value;
//'angle' div contains angle values seperated by '~'
angles=angles.replace(/\[|\]/g, '');
angles=angles.split("~");
for(var i=0;i<linePoints.length;i++){
var styleMap = new OpenLayers.StyleMap(OpenLayers.Util.applyDefaults(
{graphicName:"arrow",rotation : angles[i],strokeWidth: 3,strokeColor: "#ff0000"},
OpenLayers.Feature.Vector.style["default"]));
dirLayer.styleMap = styleMap;
dirLayer.addFeatures(linePoints[i]);
}
}
}
i am using innerHTML to add text boxes dynamically. The code sample is as follows:
<html>
<head>
<script type="text/javascript" >
var i=0;
function add()
{
var tag = "<input type='text' name='" + i + "' /> <br/>";
document.getElementById("y").innerHTML += tag;
i++;
}
</script>
</head>
<body>
<input type="button" id="x" value="Add" onclick="add();" />
<div id="y"></div>
</body>
</html
Are there any ways to add text boxes dynamically without losing values of previous text box when a new text box is added?
Similar question has been posted, but there are no answers :(
What if I want to add textbox in this situation:
function add() {
var element='<li class="ie7fix" style="width:620px;"><div class="m_elementwrapper" style="float:left;"><label class="fieldlabel" style="width:106px;float:left;padding-top:3px;" for="p1f4"><span><span class="pspan arial" style="text-align:right;font-size:14px;"><span class="ispan" xml:space="preserve"></span></span></span></label><div style="float:left;width:475px;" class="m_elementwrapper"><input type="text" style="font-family:Arial, Helvetica, sans-serif;font-size:14px;width:244px;max-width:244px;" name="' + i + '" class="fieldcontent"><div class="fielderror"></div></div></div><div style="clear:both;font-size:0;"></div></li>';
document.getElementById("addskills").innerHTML += element;
i++;
}
Yes, through DOM Manipulation:
function add() {
var tag = document.createElement('input'); // Create a `input` element,
tag.setAttribute('type', 'text'); // Set it's `type` attribute,
tag.setAttribute('name', i); // Set it's `name` attribute,
var br = document.createElement('br'); // Create a `br` element,
var y = document.getElementById("y"); // "Get" the `y` element,
y.appendChild(tag); // Append the input to `y`,
y.appendChild(br); // Append the br to `y`.
i++;
}
This doesn't trigger the browser's DOM parser like a innerHTML does, leaving everything intact.
(innerHTML forces the browser to re-parse the entire DOM, because anything could be added with innerHTML, so the browser can't predict anything, in contrast to adding a node to a element.)
Now, to add this:
<li class="ie7fix" style="width:620px;">
<div class="m_elementwrapper" style="float:left;">
<label class="fieldlabel" style="width:106px;float:left;padding-top:3px;" for="p1f4">
<span>
<span class="pspan arial" style="text-align:right;font-size:14px;">
<span class="ispan" xml:space="preserve">
</span>
</span>
</span>
</label>
<div style="float:left;width:475px;" class="m_elementwrapper">
<input type="text" style="font-family:Arial, Helvetica, sans-serif;font-size:14px;width:244px;max-width:244px;" name="' + i + '" class="fieldcontent">
<div class="fielderror">
</div>
</div>
</div>
<div style="clear:both;font-size:0;">
</div>
</li>
You'll need:
function add() {
// Create elements
var d1 = c('div'), s1 = c('span'), ip = c('input'),
d2 = c('div'), s2 = c('span'), li = c('li'),
d3 = c('div'), s3 = c('span'), la = c('label'),
d4 = c('div');
// You can "chain" `appendChild`.
// `li.appendChild(d1).appendChild(la);` is the same as `li.appendChild(d1); d1.appendChild(la);`
li.appendChild(d1).appendChild(la).appendChild(s1).appendChild(s2).appendChild(s3);
d1.appendChild(d2).appendChild(ip);
d2.appendChild(d3);
li.appendChild(d4);
setAttributes(
[li, d1, la, s2, s3, d2, ip, d3, d4],
[
{'class':"ie7fix", 'style':"width:620px;" },
{'class':"m_elementwrapper", 'style':"float:left;" },
{'class':"fieldlabel", 'style':"width:106px;float:left;padding-top:3px;", 'for':"p1f4" },
{'class':"pspan arial", 'style':"text-align:right;font-size:14px;" },
{'class':"ispan", 'xml:space':"preserve" },
{'class':"m_elementwrapper", 'style':"float:left;width:475px;" },
{'class':"fieldcontent", 'type':"text", 'style':"font-family:Arial, Helvetica, sans-serif;font-size:14px;width:244px;max-width:244px;", 'name':''+i},
{'class':"fielderror" },
{'style':"clear:both;font-size:0;" }
]
);
var br = document.createElement('br'); // Create a `br` element,
var y = document.getElementById("y"); // "Get" the `y` element,
y.appendChild(li); // Append the input to `y`,
y.appendChild(br); // Append the br to `y`.
i++;
}
// Apply a array of attributes objects {key:value,key:value} to a array of DOM elements.
function setAttributes(elements, attributes){
var el = elements.length,
al = attributes.length;
if(el === al){
for(var n = 0; n < el; n++){
var e = elements[n],
a = attributes[n];
for(var key in a){
e.setAttribute(key, a[key]);
}
}
}else{
console.error("Elements length " + el + " does not match Attributes length " + al);
}
}
// Alias for shorter code.
function c(type){
return document.createElement(type);
};
use jquery library
<html>
<head>
<script src='jquery.js' type="text/javascript"></script>
<script type="text/javascript" >
var i=0;
function add()
{
var tag = "<input type='text' name='" + i + "' /> <br/>";
var div_content=$('#y').append(tag);
i++;
}
</script>
</head>
<body>
<input type="button" id="x" value="Add" onclick="add();" />
<div id="y"></div>
</body>
</html>
I've got round this before by reading all of the values into an array before replacing the innerHTML and then writing them back again afterwards. This way you can write whatever you like into the div. Following works on all browsers that I have tried:
<html>
<head>
<script type="text/javascript" >
var i=0;
function add() {
if(i>0) {
values=new Array();
for(z=0;z<i;z++) {
values.push(document.getElementById(z).value);
}
}
var tag = '<input type="text" name="' + i + '" id="' + i + '" /> <br/>';
document.getElementById("y").innerHTML += tag;
if(i>0) {
for(z=0;z<i;z++) {
document.getElementById(z).value=values[z];
}
}
i++;
}
</script>
</head>
<body>
<input type="button" id="x" value="Add" onclick="add();" />
<div id="y"></div>
</body>
</html>
I have been looking for a way to dynamically change the length of the input field in a HTML form.
I have come across the following:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Example</title>
<script type="text/javascript">
window.onload = function() {
thelink = document.getElementById('MyLink');
linksize = thelink.value.length;
if (linksize < 10) thelink.size = 10;
if (linksize > 50) thelink.size = 50;
}
</script>
</head>
<body>
<input id="MyLink" type="text" value="http://www.domain.com/this/is/a/very/long/link/example" />
</body>
</html>
How would i adapt this to work for every input field on my very large form?
Thanks
For your case, I would give the required minimum and maximum as data-*= attributes,
For example:
<input id="MyLink" data-min="10" data-max="50" type="text" value="http://www.domain.com/this/is/a/very/long/link/example" />
Then iterate through the inputs in your form, drawing from the data attributes, and checking for the required length.
You can collect elements in a collection, either take them from the whole document or some its containing element. You can use e.g. getElementsByTagName('input');, getElementsByName('myInput'); or getElementsByClassName('shapable_input'); methods, if tags have set the corresponding attribute:
<input name="myInput" class="shapable_input" value="...." />
and then all collected tags can be tested in the loop:
window.onload = function() {
var links = document.getElementsByTagName('input');
//var linksc = links.getElementsByClassName('link');
var i, thelink, linksize;
for (i = 0; i < links.length; i++) {
thelink = links[i];
linksize = thelink.value.length;
if (linksize <= 10) {
thelink.size = 10;
}
if (linksize > 10) {
thelink.size = 50;
}
}
};
example
I have 3 checkboxes and 1 textbox
i use only these controls mentioned above ..
I want ---- when i check checkbox1 and checkbox2 then it will display in textbox1 as 1,2 as it is as the same ascending order not 1,2, or 2,1,
I use this type of coding in asp.net (VB) , i wanna use this coding for 45 checkboxes........
Can anybody solve this problem in asp.net (vb)
JS solution (needs adaptation to your markup) as question is tagged with javascript
<html>
<head>
<title>S.O. 4121588</title>
<script type="text/javascript">
var gMax = 45;
function $(aId) {
return document.getElementById(aId);
}
// generates gMax checkboxes with value from 1 to gMax
function onload() {
var form = $('theForm');
for (var i = 1; i != gMax; i++) {
var cb = document.createElement('input');
cb.setAttribute('type', 'checkbox');
cb.setAttribute('id', 'checkbox-' + i);
cb.setAttribute('value', i);
form.appendChild(cb);
}
}
// update the result textarea
function updateResult() {
var num = [ ];
for (var i = 1; i != gMax; i++) {
var cb = $('checkbox-' + i);
if (cb.checked) {
num.push(cb.getAttribute('value'));
}
}
$('result').innerHTML = num.join(", ");
}
</script>
</head>
<body onload='onload()'>
<form id="theForm"></form>
<input type="button" id="resultBtn" value="Result"
onclick="updateResult()" />
<br/>
<textarea id="result"></textarea>
</body>
</html>
Tested under Chrome 9.0.570.1 dev