Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
A MIRACLE
Sep 17, 2007

All right. It's Saturday night; I have no date, a two-liter bottle of Shasta and my all-Rush mix-tape... Let's rock.

This is actually a Coffeescript question. I don't think a Coffeescript thread exists, so this seems like the best place to ask. The Rails thread might be more appropriate.

I'm building an account page with various tabbed navs that pull from our server using AJAX. I'm trying to make it kinda SPA-ey without actually introducing a whole framework, because it wouldn't fit with the rest of the site. Anyway I have a bunch of these ProfileTab sub classes that all have exactly the same `initialize` method. I tried to remove it and just keep it in the parent but ProfileTab doesn't know about the @render method of it's children. So I have a bunch of repetitive `def initialize return super(@render) end` methods smelling up my code.

Any suggestions on ways to clean it up a bit? Here's the first twenty-five lines or so from my coffee file.

CoffeeScript code:
class ProfileTab
  initialize: (renderMethod) =>
    $.getJSON(@path, renderMethod)

  render: (data) => 
    $(@container).html(_.template($(@templateID).html(), data))

class VouchersTab extends ProfileTab
  constructor: ->
    @templateID = '#vouchers-template'
    @container = '#vouchers-table-body'
    @path = '/profile/vouchers'

  initialize: =>
    super(@render)

  render: (data) =>
    super(vouchers: data)

class OrdersTab extends ProfileTab
  constructor: ->
    @templateID = '#orders-template'
    @container = '#orders-data'
    @path = '/profile/orders'

  initialize: =>
    super(@render)

  render: (data) =>
    super(orders: data)
    $('.order-id').on 'click', (new OrderTab).initialize

Cheers! :coffee:

Adbot
ADBOT LOVES YOU

Stoph
Mar 19, 2006

Give a hug - save a life.

A MIRACLE posted:

I tried to remove it and just keep it in the parent but ProfileTab doesn't know about the @render method of it's children.

CoffeeScript code:
class ProfileTab
  initialize: () =>
    $.getJSON(@path, @render)

Maybe you had a bug somewhere else because this looks like what you want to me. In the initialize function of the parent, "this" is a real child instance with access to all its keys.

gandlethorpe
Aug 16, 2008

:gowron::m10:
Can I use bookmarklets to fill out web forms that are themselves coded in javascript?

A MIRACLE
Sep 17, 2007

All right. It's Saturday night; I have no date, a two-liter bottle of Shasta and my all-Rush mix-tape... Let's rock.

Stoph posted:

CoffeeScript code:
class ProfileTab
  initialize: () =>
    $.getJSON(@path, @render)

Maybe you had a bug somewhere else because this looks like what you want to me. In the initialize function of the parent, "this" is a real child instance with access to all its keys.

Doing this oddly works for the VouchersTab class but breaks on OrdersTab, where the render method is undefined.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

gandlethorpe posted:

Can I use bookmarklets to fill out web forms that are themselves coded in javascript?

Yes

gandlethorpe
Aug 16, 2008

:gowron::m10:
Ok then, to expand, I'm trying to streamline data entry into a web-based database that has a JS interface. This particular database is for test subjects undergoing clinical trials. Here's the source for the first of many forms. It consists of three items. The first is a textbox (for initials), the second and third both consist of three dropdown boxes for entering dates. Since it's not html, I'm assuming document.getElementById isn't going to cut it. I need help deciphering all this to identify entry fields and populate them:

code:
    <body onLoad=LD() onUnLoad=UL() tabindex=-1>
        <DIV ID="testdiv1" STYLE="position:absolute;width:144px;visibility:hidden;background-color:white;layer-background-color:white;"></DIV>
        <iframe id="HelpShim" src="javascript:false;" scrolling="no" frameborder="0"
        style="position:absolute; top:0px; left:0px; display:none;"></iframe>
        <SCRIPT>
            document.write(top.getCalendarStyles());
            top.InitCalendarControl("testdiv1", "HelpShim", this.document);
        </SCRIPT>
        <div id=multiform class=formbody style=overflow:auto>
            <SCRIPT>
                oL = top.C.location;
                dcm = this.document;

                t = top;
                d = document;
                dcm = document;
                a = d.getElementsByTagName("*");
                oF = d.forms;
                w = window;
                t.wndCur = w;
                oForm = new t.FS(w)
                 t.oLastDate = t.oDateErr = null
                 P1 = "11583;0;11579"
                o1 = t.a('21587', 5, 1, 0, '"CharSet","1"')
                 P2 = "11583;0;11572"
                o2 = t.a('21588', 7, 3, 0, '"O","DMY","R","DMY","U","0","C","1","T","0"')
                 P3 = "11583;0;11566"
                o3 = t.a('21589', 7, 3, 0, '"O","DMY","R","DMY","U","0","C","1","T","0"')

                function BTN(t, p, a, q) {
                    u = "./pfts.dll?C=TM_1&SI=40270&NM=0&EQ=" + t + "&CT=1&IP=" + oF[0].IPA.value + ';' + p + (a == 1 ? "&ID=1" : "")
                    if (q >= 0) u += q > 0 ? "&QID=" + q : "&QID=0"
                    oL.href = u
                }

                function LD() {
                    top.SBL()
                    top.AddFm(document.pf11585)
                    t.bFormEmpty = true
                }

                function UL() {
                    top.SBU()
                    t.bFormEmpty = false
                }
                t.FH3(d, 'pf11585', 'CRFBody', '')
            </SCRIPT>
            <SCRIPT>
                t.HD(d, ["IPA", "SubmitID", "CSRFID"], ["0_0;14935_0!1.000;11585_378609106251010.000!1.000", "1", "EA92944C1EC925766A3315AE3BB00EA8"]);
                t.MF(d, 0);
                t.G4(d);
                t.I4(d, 1, '1.', 1);
                t.I3(d, 50);
                t.O(d, 'Subject Initials');
                t.I5(d, 50, 0, '', '1.');
                t.TX(d, "21587", 3, 3, "", "o1", 3, '<i>(Enter a dash if no middle initial)</i>', 0, '');
                t.I6(d, 1);
                t.BA(w, 128, P1, 'o1', 0, 0, '', 0);
                t.O(d, '</TD></TR><TR>');
                t.I4(d, 1, '2.', 1);
                t.I3(d, 50);
                t.O(d, 'Date of Birth');
                t.I5(d, 50, 0, '', '2.');
                t.BDT(d, "", 4, "21588", "o2", "DMY", "", 1900, 2020, [-1, -1, -1], [], 0, "/", 0);
                t.I6(d, 1);
                t.BA(w, 128, P2, 'o2', 0, 0, '', 0);
                t.O(d, '</TD></TR><TR>');
                t.I4(d, 1, '3.', 1);
                t.I3(d, 50);
                t.O(d, 'Date Informed Consent Signed');
                t.I5(d, 50, 0, '', '3.');
                t.BDT(d, "", 4, "21589", "o3", "DMY", "", 2011, 2020, [-1, -1, -1], [], 0, "/", 0);
                t.I6(d, 1);
                t.BA(w, 128, P3, 'o3', 0, 0, '', 0);
                t.E12(d);
                t.T8(d)
            </SCRIPT>
            <SCRIPT>
                t.E9(d);
                t.HF(d);
            </SCRIPT>
        </div>
    </body>

baquerd
Jul 2, 2007

by FactsAreUseless

gandlethorpe posted:

Ok then, to expand, I'm trying to streamline data entry into a web-based database that has a JS interface. This particular database is for test subjects undergoing clinical trials. Here's the source for the first of many forms. It consists of three items. The first is a textbox (for initials), the second and third both consist of three dropdown boxes for entering dates. Since it's not html, I'm assuming document.getElementById isn't going to cut it. I need help deciphering all this to identify entry fields and populate them:

Your code is obfuscated (I really, really hope so anyway), get the original source. If you don't have that what are you doing messing around with clinical trial data?

karms
Jan 22, 2006

by Nyc_Tattoo
Yam Slacker
Don't even try to do something based on that ofuscated piece of jibber jabber. Use your browser's development tools (Chrome: press F12, firefox: install firebug then F12, IE: install another browser since its devel tools are balls) and figure out a way to get at the inputs you want.

Because filling in a form though js is primarily navigating the DOM tree I'd use jQuery to make that part way easier, but it's up to you.

gandlethorpe
Aug 16, 2008

:gowron::m10:

baquerd posted:

Your code is obfuscated (I really, really hope so anyway), get the original source. If you don't have that what are you doing messing around with clinical trial data?

The environment is created by an external company (Oracle Corp). My job, as a lowly data entry operator, is to assist with testing databases, usually by entering lots of test (fake) data. In the past, I've had to enter 100 identical subjects into a database, which I accomplished with a crude AutoHotkey script. I'd like to learn how to create a more sophisticated script.

KARMA! posted:

Don't even try to do something based on that ofuscated piece of jibber jabber. Use your browser's development tools (Chrome: press F12, firefox: install firebug then F12, IE: install another browser since its devel tools are balls) and figure out a way to get at the inputs you want.

Because filling in a form though js is primarily navigating the DOM tree I'd use jQuery to make that part way easier, but it's up to you.

Might be tricky, since supposedly the interface is only supported by IE, although I think I was able to log in on Chrome in the past. Either way, I'll have to wait until I go home to try a different browser than IE. If I am able to, how would I go about de-obfuscating it?

Movac
Oct 31, 2012
gandlethorpe, have you looked into iMacros? I've used it for some light automated form filling in the past, and it works well enough. There's an IE version.

gandlethorpe
Aug 16, 2008

:gowron::m10:
Sounds interesting, might give it a look. Can it work in the background (i.e. in a minimized browser)? Will the obfuscation be a problem?

Movac
Oct 31, 2012

gandlethorpe posted:

Sounds interesting, might give it a look. Can it work in the background (i.e. in a minimized browser)? Will the obfuscation be a problem?

It works just fine when minimized, without any interaction. Just have it loop a macro however many hundred times. iMacros works directly with the DOM, so source obfuscation is no obstacle. The query language it uses to find elements is a little obtuse, but you don't need to write it yourself: instead, record yourself filling out the form then plug in the logic to load test data. It should just work as long as the form layout doesn't change too much.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

gandlethorpe posted:

Since it's not html, I'm assuming document.getElementById isn't going to cut it.

document.getElementById will work if the element has an id attribute. It doesn't matter if the element is created from html or dynamically through javascript.

karms
Jan 22, 2006

by Nyc_Tattoo
Yam Slacker

gandlethorpe posted:

The environment is created by an external company (Oracle Corp). My job, as a lowly data entry operator, is to assist with testing databases, usually by entering lots of test (fake) data. In the past, I've had to enter 100 identical subjects into a database, which I accomplished with a crude AutoHotkey script. I'd like to learn how to create a more sophisticated script.

Good!

gandlethorpe posted:

Might be tricky, since supposedly the interface is only supported by IE, although I think I was able to log in on Chrome in the past. Either way, I'll have to wait until I go home to try a different browser than IE. If I am able to, how would I go about de-obfuscating it?

Don't worry about the existing javascript. Anything it does to change the site it has to go though the DOM (aka the site's structure), which your javascript has access to just the same. The biggest problem you're facing is viewing the DOM after the oracle js has its way with it. Doing a view > source just shows you the before picture, which is not useful in the least.

IE's developer console is definitely the worst out of the bunch because it likes to go slow as balls and/or crash for no reason at all at random intervals, but it still enables you to view the DOM as it is right now. The HTML tab is where that information lies. The Console tab allows you to input (single) lines of javascript and see its results immediately. Also, if your external javascript has a console.log(PUT SOMETHING HERE); it will show its output in this tab. Very useful.

bartkusa
Sep 25, 2005

Air, Fire, Earth, Hope
Ironically, IE has the Javascript performance profiler with the most features.

gandlethorpe
Aug 16, 2008

:gowron::m10:
So it looks like I'm limited to IE7 or 8, but that's better than nothing. Please bear with me because I'm going to be asking a lot of newbie questions. Here's where I am so far (as well as a visual for what the page actually looks like):



I used "Select element by click" to highlight the first textbox, which brought me to the highlighted part below.

code:
<input name="21587" onkeypress="return top.OK(o1,0,this)" onclick="t.OC(o1,0,this)" onfocus="t.OF(o1,0,this)" onblur="t.OB(o1,0,this)" onchange="t.OH(o1,0,this)" type="text" size="4" maxLength="3" pfobj="o1"/>
"View > source > DOM Element" gives me this:



Is this more on track to what I'm looking for? I'm guessing I can disregard all that script mess I posted before.

gandlethorpe
Aug 16, 2008

:gowron::m10:
All right, I figured out how to access and populate the form elements. Essentially, I'm navigating through the frames until I get to the element I want, then change the property. It's a lot easier than I first thought, even working with IE7's toolbar.

To enter the initials, I did this:

code:
window.frames['C'].window.frames['CRFBody'].document.getElementsByName('21587')[0].value = 'ABC'
Since they didn't assign ids to the elements for some reason, I have to go with the name, but it seems to work well enough. Now I just have to figure out how to submit the form then wait for the next page to load.

Oh, and also how to make my code prettier and more professional. Since IE7's dev tool doesn't have a console, I'm just working in notepad then pasting my code into a bookmarklet.

gandlethorpe fucked around with this message at 19:44 on Jan 14, 2013

gandlethorpe
Aug 16, 2008

:gowron::m10:
Dumb question: Do bookmarklets persist when loading a new page? If they don't, will I have to use some external script to run different bookmarklets for each page?

So far, populating elements is pretty straightforward. The real annoying thing is that there are navigation and submission buttons I need to click often, and the only way I know how to access them is by their tag name A. Something tells me there's a more efficient method than counting each A element until I get to one I want.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

gandlethorpe posted:

Dumb question: Do bookmarklets persist when loading a new page? If they don't, will I have to use some external script to run different bookmarklets for each page?

What do you mean?

Bookmarklets are short javascript snippets you run by selecting a bookmark in your browser. So in that case, they persist. Any variables you declare inside the bookmarklet do not persist, they will disappear when the page is reloaded.

If you never cause the page to be reloaded, ou can use global variables to store data.

If you want to store values between page loads, you can write them in a cookie and then read the value from the cookie when running your bookmarklet.

gandlethorpe posted:

So far, populating elements is pretty straightforward. The real annoying thing is that there are navigation and submission buttons I need to click often, and the only way I know how to access them is by their tag name A. Something tells me there's a more efficient method than counting each A element until I get to one I want.

Probably not in IE7.

With more modern browsers you might be able to use querySelectorAll / querySelector or even xpath. Or, if the page happens to be xml, you can use xpath in IE7 as well.

You could try getting some parent element with first selecting some higher-level element with getElementById, then calling getElementsByTagName on that parent-element.

so something like:
JavaScript code:
var commonParent = document.getElementById('parentElement');

var aTagsInsideParent = commonParent.getElementsByTagName('a');
But most likely there is no need to do so just for "efficiency".

Factor Mystic
Mar 20, 2006

Baby's First Post-Apocalyptic Fiction

bartkusa posted:

Ironically, IE has the Javascript performance profiler with the most features.

IE also has built in deobfuscation/js formatting. F12 -> Script -> wrench looking icon -> "Format JavaScript"

akadajet
Sep 14, 2003

Factor Mystic posted:

IE also has built in deobfuscation/js formatting. F12 -> Script -> wrench looking icon -> "Format JavaScript"

Is this different than what's in Chrome?

gandlethorpe
Aug 16, 2008

:gowron::m10:

Wheany posted:

What do you mean?

Bookmarklets are short javascript snippets you run by selecting a bookmark in your browser. So in that case, they persist. Any variables you declare inside the bookmarklet do not persist, they will disappear when the page is reloaded.

If you never cause the page to be reloaded, ou can use global variables to store data.

If you want to store values between page loads, you can write them in a cookie and then read the value from the cookie when running your bookmarklet.

One particular section of my project involves diary logs, which is just the same form done multiple times. I need to do 28 of those, so I have an array of strings for each log that determine how to fill out the form. There's a hub page that lists each completed form and has a button to start a new form, which loads a new page. I want to be able to start a new form, read the string to fill out the form, and submit (which brings me back to the hub page) then start the next form reading the next string, repeating until all the logs are done. Can I accomplish that using only one bookmarklet?

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

gandlethorpe posted:

One particular section of my project involves diary logs, which is just the same form done multiple times. I need to do 28 of those, so I have an array of strings for each log that determine how to fill out the form. There's a hub page that lists each completed form and has a button to start a new form, which loads a new page. I want to be able to start a new form, read the string to fill out the form, and submit (which brings me back to the hub page) then start the next form reading the next string, repeating until all the logs are done. Can I accomplish that using only one bookmarklet?

I don't think so.

That is more of a job for a user javascript, but for that you would need any other browser. User javascript runs automatically on page load, which means you could automate the process entirely.

Does IE7 have a bookmarks toolbar built in? You could use that to simplify your task somewhat. Instead of having to open a menu to run your bookmarklet, you could just press a button on the toolbar.

Also if you can add/replace an onclick handler on the hub page, you could append the current index in the array or even the data itself to be filled into the url of the form page, like so:
"#firstname=John,initials=J.Q.P,lastname=Public"

Then your bookmarklet could extract the data from the url (location.hash)

30 TO 50 FERAL HOG
Mar 2, 2005



I'm working on a Windows Store app the JS and I'm having problems with promises.

code:
function GetReturnValue()
{
     var ReturnValue;

     Object.DoAsyncAction().then(function(){
          ReturnValue = ResultOfAsyncAction;
          });
     
     return ReturnValue;
}
Obviously, the asyncronous call does not block, so an empty value is returned. I need this function to not end until after it completes.

30 TO 50 FERAL HOG fucked around with this message at 18:35 on Jan 16, 2013

Funking Giblet
Jun 28, 2004

Jiglightful!
Instead of
ReturnValue = ResultOfAsyncAction;

Try,

thingImTryingToSet = ResultOfAsyncAction;

Either thingImTryingToSet is a variable within scope or passed as a parameter.

Blocking is a bad idea.

30 TO 50 FERAL HOG
Mar 2, 2005



It's gotta block. That action has to happen or the application might as well crash. There is no reason for the function to have even been written asyncronously, it will return the value in O(1) baring some catastrophic failure. In which case, go ahead and freeze up the UI. IDGAF

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
That's not how async programming works. Your example is woefully incomplete and shows that you don't understand the concept, so more information about your actual problem would be appreciated.

Stoph
Mar 19, 2006

Give a hug - save a life.

BiohazrD posted:

I'm working on a Windows Store app the JS and I'm having problems with promises.

code:
Object.DoAsyncAction().then(function (result) {
    // do something with result
    console.log(result);
});
This isn't the concurrency model you want. It's the one you're stuck with. The result is given in the anonymous function as the first parameter, I assume.

Stoph fucked around with this message at 00:18 on Jan 17, 2013

dizzywhip
Dec 23, 2005

If there's no synchronous API for what you're trying to do, the proper thing to do is to make your function asynchronous as well. There's nothing wrong with that, you just might need to restructure your code a little bit to accommodate it. There's generally no way in JavaScript to block execution while waiting for an asynchronous call to return.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
Asynchronous code can be a bit of a pain in the rear end, but that's how it is, so just get used to writing function (param, callback) all the time.

30 TO 50 FERAL HOG
Mar 2, 2005



Guess ill just have to rewrite a lot of code just for Windows 8. Win 7, Android, iOS required minimal changes. Good job, Microsoft.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Uhhhh?

You wrote an app for Windows 7, Android and iOS using JS? And it wasn't asynchronous?

Wozbo
Jul 5, 2010
You could also, iunno, do an event emitter. When you have a result, listener.emit("TheshitIwaswaitingforisdone", results);

then:
code:
listener.on("TheshitIwaswaitingforisdone", function(results){
//poo poo here
});
Bue seriously, don't make your code synchronous in JS. This is a "Bad Thing."

Wozbo fucked around with this message at 19:27 on Jan 17, 2013

30 TO 50 FERAL HOG
Mar 2, 2005



Suspicious Dish posted:

Uhhhh?

You wrote an app for Windows 7, Android and iOS using JS? And it wasn't asynchronous?

Of course it is. Just this one function in particular needs to be syncronous. WINJS is the only API that doesn't provide a syncronous method.

Wozbo posted:

You could also, iunno, do an event emitter. When you have a result, listener.emit("TheshitIwaswaitingforisdone", results);

then:
code:
listener.on("TheshitIwaswaitingforisdone", function(results){
//poo poo here
});
Bue seriously, don't make your code synchronous in JS. This is a "Bad Thing."

Oh my god. Not everything needs to be asyncronous. Do you write a thread and callback for every variable assignment?

30 TO 50 FERAL HOG fucked around with this message at 22:36 on Jan 17, 2013

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

BiohazrD posted:

Of course it is. Just this one function in particular needs to be syncronous. WINJS is the only API that doesn't provide a syncronous method.

May I ask what function call this is?

BiohazrD posted:

Oh my god. Not everything needs to be asyncronous. Do you write a thread and callback for every variable assignment?

The fact that you said "thread" there makes me think you don't understand the concept.

30 TO 50 FERAL HOG
Mar 2, 2005



Suspicious Dish posted:

May I ask what function call this is?

The fact that you said "thread" there makes me think you don't understand the concept.

I'm not at work so I can't look at the code, and I don't remember off of the top of my head.

I'm normally a C++/C# programmer. So when I think asyncronous programming, I think in threads. I am aware JS does not have threads.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

BiohazrD posted:

I'm normally a C++/C# programmer. So when I think asyncronous programming, I think in threads. I am aware JS does not have threads.

C# has async/await, which don't use threads either.

30 TO 50 FERAL HOG
Mar 2, 2005



Yeah but I usually don't use them in favor of threads or BackgroundWorkers if I'm doing something UI related.

Wozbo
Jul 5, 2010
I pretty much async up everything (yes, everything). If you don't you risk being harvested/ manually stopped by whatever interpreter is running at the time (all of them can and will shut you down pretty fast).

Adbot
ADBOT LOVES YOU

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
Is there user script/bookmarklet thread? If not, is anyone else interested in such a thread?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply