How to enumerate asp.net HTML element attributes in javascript - javascript

To make a long story as short as possible (ignore this paragraph if you really just want to cut to the chase):
I'm using CuteEditor to edit very specific pages of controls. In the page viewer application these controls use HTML5 canvii to do all sorts of funky anim stuff, but in CuteEditor (where it's not practical to do the same thing) they are represented by IMG elements for editability. These controls have a bunch of properties, and this is all saved and loaded from an SQL database. Different types of control have different possible types of properties, and in CuteEditor these are stored as attributes of the element (such as PipColour="Green") I have created a custom tab for the CuteEditor IMG editor dialog, which when the control type is changed, an SQL database is called to get all the possible properties so the dialog can be populated with the relevant input controls.
Now, the chase:
In CuteEditor, custom dialog tabs use a .ascx file with SyncToView() and SyncTo(element) javascript methods to get and set the attributes of the element being edited, using
element.<attributename>
Since I don't necessarily know what attributes 'element' will have or what they will be called, is there a way to enumerate through them all by name?

You can use the following code snippet, it will give you the basic idea of getting Attributes
var element = document.getElementById("someId");
var arr = [];
for (var i=0, attrs=element.attributes, l=attrs.length; i<l; i++){
arr.push(attrs.item(i).nodeName);
values.push(attr.nodeValue);
}

Related

Linking XML elements to page items in InDesign

I can check the XML of selected text like this:
app.selection[0].associatedXMLElements[0];
But in my research, I am still left scratching my head about how to do the most basic thing with XML using script: how do I assign XML to items? I can manually do this by opening the structure pane, then dragging the element over the desired frame on the page. If it's possible the old fashioned way, I imagine it's possible with script.
How do I link an existing XML element to an existing page item?
The above code only seems to work on selected text. If I select a graphic, it won't run.
How can I link XML to a selected graphic?
You can reference your xml node and your text frame and use placeXML
myXMl = myDoc.xmlElements[0];
var myXmlNode = myXMl.evaluateXPathExpression("/myXML/node1")[0];
var myFrame = app.activeDocument.pages[0].textFrames[0];
myXmlNode.placeXML(myFrame);
The advantage of this approach is that any aid:pstyle or aid:cstyle will be linked to existing matching style automaticaly
The alternative is to select the value of the node as text and place it into the text frame at insertion point:
myXMl = myDoc.xmlElements[0];
var myText = myXMl.xpath("/myXML/node1[1]/text()");
var myFrame = app.activeDocument.pages[0].textFrames[0];
myFrame.parentStory.insertionPoints[-1].contents = myText + '\r';
there are two specific properties. AssociatedXMLElement is for pageItems including textFrames and may be null if no tag is applied. AssociatedXMLElements only applies to text objects (characters, words…) because they can have several tags applied. Note that a non tagged text return an empty array and not null.
Associating tags to pageItems require that you first create or target existing xmlElements then use myInDesignObject.markup ( myXMLElement ).
EvaluateXPathExpression as Nicolai suggested is interesting once you want to browse through your XML structure. But it's sometimes quicker indeed to investigate associated XMLElement from the object rather than investigating the xml structure.
FWIW

How to get visible div inputs in a page through php?

I have been trying to get the names of the visible div inputs there are two visible..!
but it's getting difficult for me..I got a way out with javascript but I really want to to do it in PHP..! as names of divs and inputs are changing on every visit and reloading the page..! so it's quite difficult to target by any permanent name or ID..!
Here is how I got it from a user in javascript :
var isCandidateRegion=function(node){
return (node.innerText.indexOf('Username')>-1 && node.innerText.indexOf('Hours')>-1);
};
//Find the last table in th document that contains 'Username' and 'Hours'
var candidateRegions=[].filter.call(document.querySelectorAll('table'),isCandidateRegion);
var targetRegion=candidateRegions[candidateRegions.length-1];
var isVisible=function(node){
return (node.offsetWidth && node.offSetWidth >0) || (node.offsetHeight && node.offsetHeight>0);
};
var inputs=[].filter.call(targetRegion.querySelectorAll('input'),isVisible);
var usernameInput=inputs[0].name;
var hoursInput=inputs[1].name;
console.log(usernameInput,hoursInput);
So what I want is to get the names in a php variable so that I can use it in php now..I can see the names of the inputs in console but I want it to store in a PHP variable..!
So if there is any way please or alternative of using jQuery or Javascript as PHP will be great..!
PHP is a server side language which for all intents and purposes relating to how I understand your question, is basically there only to serve and read HTML code. Unless you have something actually written on a DOM element, there is no way for PHP to know whether it is visible or not, as it can't automatically detect its styling like JavaScript can.
JavaScript on the other hand is designed for working with DOM page elements and detecting styles, or manipulating elements.
To make your PHP see what elements are visible, you need to explicitly tell PHP what is and isn't visible by putting it into HTML using JavaScript (or jQuery). This can be done by:
Adding a specific class onto your div that you want to make known to PHP e.g. <div class="visible"> ... </div> or <div class="hidden"> ... </div>.
Adding a data attribute to your element e.g. <div data-visibility="visible"> ... </div> or <div data-visibility="hidden"> ... </div>
In your PHP, on the method reading info from the page you can traverse the DOM and get all div's that have the appropriate class or attribute.

Make HTML visible inside Iframe

I'm making my own WYSIWYG. I've got two buttons: "Visualize" and Show Source.
I've got an iframe (rich text editor) that contains a huge piece of HTML code. First time it's loaded it shows all the elements visually. Once Show Source is pressed the innerHTML text (of the visualized html) is shown. But how can I make the HTML text visual again, when the Visualize button is pressed?
content.document.body.innerText holds the HTML that needs to be visualized.
(content = id of the iframe)
$('#Visualize').click(function()
{
// Make HTML visible
});
With the html code that you already have you and to show a preview in a div, correct? Just use the html function.
$('#Visualize').click(function(){
$('#myShowDiv').html(content.document.body.innerText);
});
If you're using an iframe and that iframe is only intended to hold the actual page source being edited, then you're going to need variables on your parent frame that hold the actual source. I would recommend keeping it separate and then use the following to perform switches:
var actualSource = content.document.body.innerHTML;
// just something to initialize it
// You should probably keep it in a global object instead of as a var
$('#Visualize').click(function()
{
actualSource = content.document.body.innerText;
content.document.body.innerHTML = "";
content.document.body.innerHTML= actualSource;
});
I would imagine that you have methods that are capturing the source, but I would imagine you'd want to capture the actual source as it is at that moment. I'm not sure what you're doing with the actual editing piece (is it a div that is editable? is it a text area?), but in order to perform the showing, it should just be a matter of toggling the innerHTML and innerText between the two settings. The real catch will be monitoring the actual controls affected by this change.

Javascript execution order

I want to give a static javascript block of code to a html template designer, which can be:
either inline or external or both
used once or more in the html template
and each block can determine its position in the template relative to the other javascript code blocks.
An example could be image banners served using javascript. I give code to template designer who places it in two places, once for a horizontal banner in the header and once for a vertical banner. The same code runs in both blocks but knowing their positions can determine if to serve a horizontal or a vertical image banner.
Make sense?
Another example: Say you have the same 2 javascript tags in a web page calling an external script on a server. Can the server and/or scripts determine which javascript tag it belongs to?
NOTE: Can we say this is a challenge? I know that I can avoid this puzzle very easily but I come across this on a regular basis.
JavaScript code can locate all <script> elements on the page and it can probably examine the attributes and the content to check from which element it came from. But that's probably not what you want.
What you want is a piece of JavaScript which replaces tags on the page with ad banners. The usual solution is to add a special element, say a IMG, for this and give that IMG an id or a class or maybe even a custom attribute (like adtype="vertical") and then use JavaScript to locate these elements and replace the content by changing the src attribute.
For example, using jQuery, you can should your images like so:
<img src="empty.gif" width="..." height="..." class="ad" adtype="..." />
Then you can locate each image with
$('img.ad')
[EDIT] Well, the server obviously knows which script belongs into which script tag because it inserts the script. So this is a no-brainer.
If the script wants to find out where it is in the DOM, add something which it can use to identify itself, say:
<script>var id= '329573485745';
Then you can walk all script tags and check which one contains the value of the variable id.
If you call an external script, then you can do the same but you must add the ID to the script tag as you emit the HTML:
<script id="329573485745" src="..." />
Then the external script can examine the DOM and lookup the element with this id. You will want to use an UUID for this, btw.
This way, a piece of JS can locate the script tag which added itself to the page.
Best thing would probably be to make an insert once function, and then have him insert only the function call where needed.
Like this:
timescalled=0
function buildad(){
var toinsert="" //Code to generate the desired piece of HTML
document.write(toinsert)
timescalled+=1 //So you can tell how many times the function have been called
}
Now a script block calling the function can simply be inserted wherever a banner is needed
<script type="text/javascript">buildad()</script>
Thanks for the tips everyone but I'll be answering my own question.
I figured out several ways of accomplishing the task and I give you the one which works nicely and is easy to understand.
The following chunk of code relies on outputting dummy divs and jQuery.
<script>
// Unique identifier for all dummy divs
var rnd1="_0xDEFEC8ED_";
// Unique identifier for this dummy div
var rnd2=Math.floor(Math.random()*999999);
// The dummy div
var d="<div class='"+rnd1+" "+rnd2+"'></div>";
// Script which :
// Calculates index of THIS dummy div
// Total dummy divs
// Outputs to dummy div for debugging
var f1="<script>$(document).ready(function(){";
var f2="var i=$('."+rnd1+"').index($('."+rnd2+"'))+1;";
var f3="var t=$('."+rnd1+"').length;";
var f4="$('."+rnd2+"').html(i+' / '+t);";
var f5="});<\/script>";
document.write(d+f1+f2+f3+f4+f5);
</script>
Why not not just place the function call on the page instead of the entire code block? This way you can pass in a parameter to tell it what type of advertisement is needed?
BuildAd('Tower');
BuildAd('Banner');
Javascript itself has no clue of it's position in a page. You have to target a control on the page to get it's location.
I don't think it is possible for JavaScript code to know where it was loaded from. It certainly doesn't run at the point it is found, since execution isn't directly tied to the loading process (code usually runs after the whole DOM is loaded). In fact, in the case of externals, it doesn't even make sense, since only one copy of the code will be loaded no matter how many times it is encountered.
It shouldn't be the same code for each banner - there will be a parameter passed to whatever is serving the image banner which will specify the intended size.
Can you give a specific example of what you need this for?
To edit for your recent example: The simple answer is no. I could help you approach the problem from a different direction if you post details of your problem
The term "static block of code" leaves a lot of room for interpretation.
Inline scripts (e.g., ones that rely on document.write and so must be parsed and executed during the HTML parsing phase) cannot tell where they are in the DOM at runtime. You have to tell them (as in one of the first answers you got).
I think you'll probably find that you need to change your approach.
A common way to keep code and markup separate (which is useful when providing tools to HTML designers who aren't coders) is to have them use a script tag like so:
<script defer async type='text/javascript' src='pagestuff.js'></script>
...which then triggers itself when the page is loaded (using window.onload if necessary, but there are several techniques for being triggered earlier than that, which you want because window.onload doesn't trigger until the images have all loaded).
That script then looks for markers in the markup and manipulates the page accordingly. For instance (this example uses Prototype, but you can do the same with raw JavaScript, jQuery, Closure, etc.):
document.observe("dom:loaded", initPage);
function initPage() {
var verticals = $$('div.vertical');
/* ...do something with the array of "vertical" divs in `verticals`,
such as: */
var index;
for (index = 0; index < verticals.length; ++index) {
vertical.update("I'm vertical #" + index);
}
}
The designers can then have blocks on the page that are filled in by code which they flag up in a way that's normal for them (classes or attributes, etc.). The code figures out what it should do based on the classes/attributes of the blocks it finds when it runs.

html & javascript: How to store data referring to html elements

I'm working on a web application that uses ajax to communicate to the server.
My specific situation is the following:
I have a list of users lined out in the html page. On each of these users i can do the following: change their 'status' or 'remove' them from the account.
What's a good practice for storing information in the page about the following:
the user id
the current status of the user
P.S.: I'm using jQuery.
There is jQuery's data function
$('li').data('userid',uid); // sets the value of userid
uid = $('li').data('userid'); // retrieves the value of userid
official documentation: http://docs.jquery.com/Data
There is a lot of debate as to what is best to use. You can store the data a lot of ways, and they all make someone happy - custom attributes will of course not validate if you use XHTML, and using classes to store one or two bits of data is clumsy at best and only gets worse with the amount of things you want to know. Personally, not only am I not a big fan of XHTML, I am also not much of a validation nazi, so I recommend going with the custom attributes.
There is, however, an option that reconciles custom attributes with standards: data- attributes. As John Resig (the author of jQuery) writes about in his blog, this is a new attribute being introduced in HTML5 that allows you to specify custom data attributes with the data- prefix. So a perfectly valid element might look like this:
<ul>
<li data-userid='5' data-status='active'>Paolo Bergantino</li>
</ul>
This has the upside that while you are still using custom attributes which may be bad if you are using XHTML, your code is going to age very well as this is the way that we will be storing data related to a particular item in the future.
Some further reading is Attributes > Classes: Custom DOM Attributes for Fun and Profit.
Perhaps using custom attributes, so for a user's list element, add attributes for the variables:
<li uid="theuserid" ustatus="thestatus"></li>
The values can then be got with the attr function:
$("li").attr("uid")
And
$("li").attr("ustatus")
Note: The selectors will need to be changed, obviously
Please note that there are differing opinions on the use of custom attributes - however, this should be fine for every major browser. It is also the least complex solution I can think of. It doesn't require jumping to sibling elements to get data, or finding elements nearby, which can all add a small amount of overhead to processing - I try to minimise the amount of extra bloat I add to the DOM when doing such things.
jQuery Data
If you want to store custom data against a jQuery object, use the data function.
$('#myField').data('name', 'Jack');
var name = $('#myField').data('name');
HTML5 data-* Attributes
You can also use the HTML5 data-* attributes, though the APIs for accessing these are only partially supported by the different browsers. Here's some more information about that.
<div data-userid="123" class="user-row">
programmatically:
$('#myElement').attr('data-fruit', 'apple');
// or
document.getElementById('myElement').dataset.fruit = 'apple';
Hidden Fields
If you want to do things the old browser-compatible way and stuff the metadata directly into your html, you can use hidden fields. It's a bit cruder but easy enough to do.
<input type="hidden" name="UserID" value="[userid]" />
You can easily use jQuery selectors to query your list and find html blocks that contain user items that have the relevant hidden fields that match the metadata you are querying for.
In this case, I think custom attributes might be overkill. You can store the user-id in the id-attribute, since there will only be one instance of the user in the list, right? Also, the status of the user could be stored in the class-attribute. In this way, each user could be given different styling in CSS, such as green for active, yellow for a non-activated account, and red for a suspended account.
The code for fetching the status will, however, be a little more complex compared to using a custom attribute (But only if you also want to have multiple classes). On a more positive note, the HTML will validate with this approach whereas it would not with custom attributes.
<ul id="userList">
<li id="uid123" class="active">UserName X</li>
<li id="uid456" class="suspended">Mr. Troll</li>
</ul>
/**
* Simple function for searching (strict) for a value in an array
* #param array arr The array to look in
* #param mixed val The value to look for in arr. Note that the value is looked for using strict comparison
* #return boolean true if val is found in arr, else false
*/
function searchArray(arr, val) {
for(var i = 0, len = arr.length; i < len; i++) {
if(arr[i] === val) {
return true;
}
}
return false;
}
/**
* Gets a known status from a string of class names. Each class name should be separated
* by a space.
* #param string classNames The string to check for a known status
* #return string|false The status if found in classNames, else false
*/
function getStatus(classNames) {
// The different statuses a user can have. Change this into your own!
var statuses = ['active', 'suspended', 'inactive'],
nameArr = classNames.split(" ");
for(var i = 0, nameLen = nameArr.length; i < nameLen; i++) {
// If we find a valid status among the class names, return it
if(searchArray(statuses, nameArr[i])) {
return nameArr[i];
}
}
return false; // We didn't find any known status in classNames
}
var id = $("li").attr("id"); // Fetches the id for the first user
var status = getStatus($("li").attr("class")); // Fetches the status of the first user
The metadata plugin to jquery is your answer.
<html >
<head>
<script src="/js/jquery-1.3.2.js"></script>
<script src="/js/jquery.metadata.js"></script>
</head>
<body>
<ul>
<li type="text" class="{UID:'1',status:'alive'}">Adam</li>
<li type="text" class="{UID:'2',status:'alive'}">Bob</li>
<li type="text" class="{UID:'3',status:'alive'}">Carol</li>
</ul>
<script>
$('li').each(function(){window.console.log($(this).metadata().UID)});
</script>
</body>
</html>
There are various ways of doing it depending on the kind of data you are storing and how much information you are storing in the page in general. It's best to devise a consistent scheme so you can write a simple library call to do the work. For example,
You can store data in the class of a particular element. This may require additional wrapper elements in order to be able to provide an additional class to drive your CSS. This also restricts the storable content format. User ID may well fit into a class attribute.
You can store data in an unused href of a Javascript activated link. This has the additional feature of showing the data in the status bar as part of the URL on rollover. For instance you can store '#userid' or even just 'userid' in the href.
You can store data in additional elements. For instance you can have a nested div with a class that indicates storage which also triggers CSS to take the element out of the display. This is the most general and extensive support you can probably arrange in page.
Rather than a nested div you could also use nested input tags with type="hidden". This is kind of more expected / traditional and doesn't require CSS to take them out of the display. You can use the id attribute to identify these inputs, or you can use the location on the page. For instance, put them inside the link that the user clicks and then just search inside the current link in the onclick handler.
To answer the question of "how to get it into the document in the first place", I suggest a layout similar to this:
<ul id="users">
<li id="someUserId" class="someStatus">Some Username</li>
<li id="someOtherUserId" class="someOtherStatus">Some Username</li>
</ul>
This allows you to easily select a lot of info about your users:
$('#users > li') // all user elements
$('.someStatus') // all users of a particular status
Then in your event handlers it's also easy to get the current status:
$(this).attr('class') //get current status once you have a user element selected.
Another alternative is to dump javascript to the page and simply have it use the jquery data functionality to store the data as soon as the page loads. You'd still need an id on the element in order to find the right one though.

Categories

Resources