I'm writing a script to login to an internal html site, click around to the appropriate place, click on a specific row in an HTML table, and click a submit button. I'm pretty much there, except I can't figure out how to click the correct row - or any row for that matter.
Here is the source of the table: HTML Source
Here is what I've tried so far after navigating to the page with the table of interest (with no results, but no errors):
Set mainTable = IE.Document.getElementByID("main").contentwindow.document
mainTable.getElementsByName("acq_scenario.acq_scenario_summary").Item(0).getElementsByTagName("tr").Item(0).getElementsByTagName("td").Item(3).focus
mainTable.getElementsByName("acq_scenario.acq_scenario_summary").Item(0).getElementsByTagName("tr").Item(0).getElementsByTagName("td").Item(3).click
The code below tries to change the attributes in the HTML table based on changes that I've observed when manually clicking on a cell, but these changes have no effect on the view of the table (the row should be highlighted when a cell within it is clicked) and still don't allow me to click the submit button, which requires a row to be selected:
currScenario = mainTable.getElementsByName("acq_scenario.acq_scenario_summary").Item(0).getElementsByTagName("tr").Item(1).getElementsByTagName("td").Item(2).realValue 'gets string value for "Current Scenario" field, which I've unsuccessfully tried to use to manually update the "selected" attribute in the table
mainTable.getElementsByName("acq_scenario.acq_scenario_summary").Item(0).setAttribute "selected", "ScenarioName=" & currScenario
mainTable.getElementsByName("acq_scenario.acq_scenario_summary").Item(0).getElementsByTagName("tr").Item(0).setAttribute "class", "Skin_Selection_Color"
mainTable.getElementsByName("acq_scenario.acq_scenario_summary").Item(0).getElementsByTagName("tr").Item(0).style.setAttribute "highlight", "true"
I am a little fuzzy on what you need, but I think that using css for the row highlight and a onClick for the cell selection..
"the row should be highlighted when a cell within it is clicked"
CSS:
#msg_table tr:hover{background-color:white; }
Javascript:
/* create HTML table in Javascript */
for (var j = 0; j < search_results_length; j++){
// get zebra striping
if (j % 2 == 0){
//even
zebra = "zebra_0";
}else{
//odd
zebra = "zebra_1";
}
...
myTable+="<tr class='" + zebra + "' onClick='collapse_section_switch(" + j + ")'>"
/* row click here */
myTable+="<td align='right' onClick='balance_stuff(\"search_results[j].customer_number\")'>" + search_results[j].customer_balance + "</td>"
/* cell click here */
...
}
Does this help at all?
I still don't understand why the .click() command wouldn't click on the cell, but it turns out the answer was to use .FireEvent("onmouseup").
Related
Dynamic apply the costom css to tabulator table cell
I need to change the style of "ID" column depands on dynamic number. It was done as you can see the tail of my codes but use SPAN tag to make it works.
Of coz i want to use CSS style sheet to make it look nice and i tried somethings like:
<div class="myclass">ID</div>
<font class="myclass">ID</font>
to make it work but fail.
How can i add costom CSS to tabulator table cell?
Or any better suggestion for my case?(Dynamic apply the costom css to tabulator table cell)
var table = new Tabulator("#table_1", {
height:"100%",
rowHeight:40,
layout:"fitColumns",
movablecolumns:true,
vertAlign:"middle",
columns:[
{title:"name", width:25,hozAlign:"center"},
{title:"age", width:80, hozAlign:"left" },
{title:"sex", width:25,hozAlign:"center",headerSort:false, headerVertical:true},
{title:"ID", width:25, hozAlign:"center", headerVertical:true,
formatter:function(cell, formatterParams){
var value = cell.getValue();
if(value <= 3){
return "<span style='width:20px;height:20px;background-color:blue;color:white;'>" + value + "</span>"
}else{
return "<span style='width:20px;height:20px;background-color:red;color:white;'>" + value + "</span>"}
}
},]})
Let's have contenteditable div. Browser itself manage undo on it.
But when additional content changes (or touching selection ranges) are made from script (in addition to user action) then it stops behave as user expected.
In other words when user hit Ctrl+Z then div content is not reverted to previous state.
See following simplified artificial example:
https://codepen.io/farin/pen/WNEMVEB
const editor = document.getElementById("editor")
editor.addEventListener("keydown", ev => {
if (ev.key === 'a') {
const sel = window.getSelection()
const range = window.getSelection().getRangeAt(0)
const node = range.startContainer;
const value = node.nodeValue
node.nodeValue = value + 'aa'
range.setStart(node, value.length + 2)
range.setEnd(node, value.length + 2)
ev.preventDefault()
}
})
All written 'a' letters are doubled.
Undo is ok as long as there is no 'a' typed.
When user typed 'a' (appended to text as double 'aa') and hits Ctrl+Z, then he expects both 'a' will be removed and cursor moves back to original position.
Instead only one 'a' is reverted on undo and second one added by script remain.
If event is also prevented by preventDefault() (which is not needed in this example, but in my real world example i can hardly avoid it) then all is worse.
Because undo reverts previous user action.
I could images that whole undo/redo stuff will be managed by script, but it means implementation of whole undo/redo logic. That's too complicated, possible fragile and with possible many glitches.
Instead I would like tell browser something like that there is atomic change which should be reverted by one user undo. Is this possible?
You can store the "revisions" in an array, then push the innerHTML of the div to it whenever you programmatically change the innerHTML of it.
Then, you can set the innerHTML of the div to the last item in the revisions array whenever the user uses the Ctrl + Z shortcut.
const previousRevisions = []
function saveState() {
previousRevisions.push(editor.innerHTML)
}
function undoEdit() {
if (previousRevisions.length > 0) {
editor.innerHTML = previousRevisions.pop();
}
}
const editor = document.getElementById("editor")
editor.addEventListener("keydown", ev => {
if (ev.key === 'a') {
saveState()
const sel = window.getSelection()
const range = window.getSelection().getRangeAt(0)
const node = range.startContainer;
const value = node.nodeValue
node.nodeValue = value + 'a'
range.setStart(node, value.length + 1)
range.setEnd(node, value.length + 1)
} else if (ev.ctrlKey && ev.key == 'z') {
undoEdit()
}
})
#editor{width:600px;min-height:250px;border:1px solid black;font-size:24px;margin:0 auto;padding:10px;font-family:monospace;word-break:break-all}
<div id="editor" contenteditable="true">type here </div>
The benefit of this solution is that it will not conflict with the browser's native Ctrl + Z shortcut behavior.
Make the parent a div (if it isn't) and make it so it adds spans inside of it every time the user taps a so the new span and set it's id to span-keyword will have aa as the value / text. Then check if the users cursor is at the beginning of it and check if there is no other text in-front of it and the user did no other action in it. If there is no text and no other actions happened do this:
document.getElementById('span-keyword').remove();
I'm generating a table using xslt, but for this question I'll keep that side out of it, as it relates more to the actual generated structure of a html table.
What I do is make a vertical table as follows, which suits the layout needed for the data concerned that originated in a spreadsheet. Example is contrived for brevity, actual data fields contain lengthy strings and many more fields.
Title: something or rather bla bla
Description: very long desription
Field1: asdfasdfasdfsdfsd
Field2: asdfasfasdfasdfsdfjasdlfksdjaflk
Title: another title
Description: another description
Field1:
Field2: my previous field was blank but this one is not, anyways
etc.
The only way so far I found to generate such a html table is using repeating tags for every field and every record e.g.:
<tr><th>Title</th><td>something or rather bla bla</td></tr>
<tr><th>Description</th><td>very long desription</td></tr>
...
<tr><th>Title</th><td>another title</td></tr>
<tr><th>Description</th><td>another description</td></tr>
...
Of course this is semantically incorrect but produces correct visual layout. I need it to be semantically correct html, as that's the only sane way of later attaching a filtering javascript facility.
The following correct semantically produces an extremely wide table with a single set of field headers on the left:
<tr><th>Title</th><td>something or rather bla bla</td><td>another title</td></tr>
<tr><th>Description</th><td>very long desription</td><td>another description</td></tr>
...
So to summarise, need a html table (or other html structure) where it's one record under another (visually) with repeating field headers, but the field headers must not be repeated in actual code because that would wreck any record based filtering to be added later on.
Yo. Thanks for updating your question, and including some code. Typically you'd also post what you've tried to correct this issue - but I'm satisfied enough with this post.
Since you want the repeating headers in vertical layout (not something I've seen often, but I can understand the desire), you don't have to modify the HTML formatting, just use a bit more JavaScript to figure it out. I haven't gone through and checked to see if I'm doing things efficiently (I'm probably not, since there are so many loops), but in my testing the following can attach to a vertical table and filter using a couple variables to indicate how many rows there are in each entry.
Firstly, here's the HTML I'm testing this one with. Notice I have a div with the id of filters, and each of my filter inputs has a custom attribute named filter that matches the header of the rows they are supposed to filter:
<div id='filters'>
Title: <input filter='Title'><br>
Desc: <input filter='Description'>
</div>
<table>
<tr><th>Title</th><td>abcd</td></tr>
<tr><th>Description</th><td>efgh</td></tr>
<tr><th>Title</th><td>ijkl</td></tr>
<tr><th>Description</th><td>mnop</td></tr>
<tr><th>Title</th><td>ijkl</td></tr>
<tr><th>Description</th><td>mdep</td></tr>
<tr><th>Title</th><td>ijkl</td></tr>
<tr><th>Description</th><td>mnop</td></tr>
<tr><th>Title</th><td>ijkl</td></tr>
<tr><th>Description</th><td>mnop</td></tr>
</table>
Here are the variables I use at the start:
var filterTable = $('table');
var rowsPerEntry = 2;
var totalEntries = filterTable.find('tbody tr').size() / rowsPerEntry;
var currentEntryNumber = 1;
var currentRowInEntry = 0;
And this little loop will add a class for each entry (based on the rowsPerEntry as seen above) to group the rows together (this way all rows for an entry can be selected together with a class selector in jQuery):
filterTable.find('tbody tr').each(function(){
$(this).addClass('entry' + currentEntryNumber);
currentRowInEntry += 1;
if(currentRowInEntry == rowsPerEntry){
currentRowInEntry = 0;
currentEntryNumber += 1;
}
});
And the magic; on keyup for the filters run a loop through the total number of entries, then a nested loop through the filters to determine if that entry does not match either filter's input. If either field for the entry does not match the corresponding filter value, then we add the entry number to our hide array and move along. Once we've determined which entries should be hidden, we can show all of the entries, and hide the specific ones that should be hidden:
$('#filters input').keyup(function(){
var hide = [];
for(var i = 0; i < totalEntries; i++){
var entryNumber = i + 1;
if($.inArray(entryNumber, hide) == -1){
$('#filters input').each(function(){
var val = $(this).val().toLowerCase();
var fHeader = $(this).attr('filter');
var fRow = $('.entry' + entryNumber + ' th:contains(' + fHeader + ')').closest('tr');
if(fRow.find('td').text().toLowerCase().indexOf(val) == -1){
hide.push(entryNumber);
return false;
}
});
}
}
filterTable.find('tbody tr').show();
$.each(hide, function(k, v){
filterTable.find('.entry' + v).hide();
});
});
It's no masterpiece, but I hope it'll get you started down the right path.
Here's a fiddle too: https://jsfiddle.net/bzjyfejc/
I'm trying to add value to the current value of an input text field in AS3.
EXAMPLE: I have a few buttons and each button has a value, when i click on each button, the value of that button gets copied/inserted into a text input field on the stage.
further explanation:
button 1 value is (BALL)
button 2 value is (Book)
button 3 value is (Pen)
button 4 value is (cup)
etc etc ....
I have an empty input field on the stage called rest_Text.text.
so when I click on any of the buttons above, the value of that button gets copied inot the rest_Text.text...
and the final result would be something like this in the rest_Text.text:
BALL, Book, Pen
my current code is this:
function clipClick(e:Event):void {
MovieClip(root).main.loginHolder.rest_Text.text = e.target.clickTitle;
}
the code above will delete the current value and replaces it with a new one! but i need to add each value to the current one without deleting the old value.
any help would be appreciated.
Thanks in advance.
You can concatenate strings using the addition operator (+). For example:
trace(btn1.clickTitle + btn2.clickTitle + btn3.clickTitle);
//traces "BALLBookPen"
Adding on to an existing string is done with addition assignment (+=). Since you want a comma and space between each string, this is how you'd rewrite your function:
function clipClick(e:Event):void {
MovieClip(root).main.loginHolder.rest_Text.text += ", " + e.target.clickTitle;
}
I have created a simple text chat application for android device using flex 4 and action script 3. in the text chat I have given a option for change font color. I have used "TextInput" for enter text message and "Textarea" for shows the chat messages. when I change the color of the text, all the lines in the "textarea" color has been changing.
textoutput.setStyle("color",textInput.getStyle("color"));
textoutput.text += userNameInput.text + ": " + msg + "\n";"
this is the code I have used. but I need to change the color for every line in the "textarea".
In the other hand, i have created the panel for display chat, and dynamically created the label for the message and dynamically I have changed the color but all the lines are merging in same line. I need to add line break for every dynamic label in the panel window.
var mylabel:Label=new Label();
mylabel.setStyle("color",textInput.getStyle("color"));
mylabel.text += userNameInput.text + ": " + msg + "\n";
panelId.addElement(mylabel);"
this is the code I have used for adding dynamic label into Panel . can any one kindly suggest me some idea for solving any one of this problem means that should be very helpful for me. thanks in advance.
Here is some info that might be helpful , from http://help.adobe.com/en_US/as3/dev/WS8d7bb3e8da6fb92f-20050207122bd5f80cb-7ff5.html
Formatting ranges of text within a text field
A useful method of the flash.text.TextField class is the setTextFormat() method. Using setTextFormat(), you can assign specific properties to the contents of a part of a text field to respond to user input, such as forms that need to remind users that certain entries are required or to change the emphasis of a subsection of a passage of text within a text field as a user selects parts of the text.
The following example uses TextField.setTextFormat() on a range of characters to change the appearance of part of the content of myTextField when the user clicks the text field:
var myTextField:TextField = new TextField();
myTextField.text = "No matter where you click on this text field the TEXT IN ALL CAPS changes format.";
myTextField.autoSize = TextFieldAutoSize.LEFT;
addChild(myTextField);
addEventListener(MouseEvent.CLICK, changeText);
var myformat:TextFormat = new TextFormat();
myformat.color = 0xFF0000;
myformat.size = 18;
myformat.underline = true;
function changeText(event:MouseEvent):void
{
myTextField.setTextFormat(myformat, 49, 65);
}