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
Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

hooah posted:

I'm going through Stephen Grider's udemy course on React and Redux, and at one point he uses the Sparklines library to create some charts. These look fine on Chrome, but on Firefox they render enormous, and don't change size regardless of the parameters I give for height and width. Is this a known problem with Firefox, or is something else going on? Here's the JSX I'm using for a chart:

JavaScript code:
<div>
    <Sparklines height={120} width={180} data={props.data}>
        <SparklinesLine color={props.color} />
    </Sparklines>
</div>

Could be the library uses some CSS / SVG combo that FF doesn't like? Any github issues open about it on the repo?

Adbot
ADBOT LOVES YOU

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

CodfishCartographer posted:

I actually wound up running into another problem - it doesn't seem to update as often as it should. Even with it updating 1000 times a second, it would only fill up about a quarter of the way per second. I lowered the progress bar max to just be 250 and then it appears to be working, but I know it's not perfect and there's something wrong under the hood but again, I can't quite figure it out. I looked at the java console and it's getting to around 250ish, but moving to quickly for me to pinpoint its exact stopping spot. It feels like only one out of every 4 is actually filling up the progress bar?

You can never trust the requested delay being accurate in any language or framework. (Actually, If you're doing embedded work and working on assemly and have counted your cycles, you can)

Anyway: Save the current time from before you make your delay request, then request your delay. When your code runs, compare the current time to the time you saved from before you made the call, then animate your thing according to the difference between the two values.

Some frameworks make this easier by just telling you the actual delay when your code is run.

Here is an example:
JavaScript code:
var requestedDelay = 17;

var startTime = window.performance.now();

setTimeout(function() {
    var endTime = window.performance.now();
    console.log('actual delay:' + (endTime - startTime) + 'ms');
}, requestedDelay);
In my case, the actual delay is fractions of a millisecond longer than the requested delay, but those fractions add up

Wheany fucked around with this message at 09:10 on May 6, 2017

hooah
Feb 6, 2006
WTF?

Lumpy posted:

Could be the library uses some CSS / SVG combo that FF doesn't like? Any github issues open about it on the repo?

Didn't get around to checking the Sparklines repo, but I did remember that udemy has a Q&A for each video and a bit later when you make three charts, several people had a problem where they weren't all the same size. The fix is to either use svgHeight and svgWidth or an older version of Sparklines.

Dominoes
Sep 20, 2007

Yo bros. Redux reducer Q: What's the best way to edit sub-components of objects in reducers? I just read This guide, which says explicitly NOT to do my current approach of _.cloneDeep at the start of the reducer, for performance reasons; IIRC y'all advised the same. The examples given show code that looks pretty obfuscated, in the name of immutability. I've cut my teeth on Immutable.JS for a simple example, and it seems like a pretty big commitment: It involves syntax changes throughout the codebase. (ie using .get syntax). It also converts objects into Maps, which isn't always appropriate.

JavaScript code:
        let newState = _.cloneDeep(state)
...

        case 'addPuckMeeting':  // ie a puck is dropped in place
            meeting = _.find(newState.meetings, m => m.fields.number == action.meetingNumber)
            meeting.fields.people.push(action.person)

            return newState
The code above is clear, but inefficient. Using Immutable.js would be efficient, and clear in the Reducer, but would involve mangling the entire rest of the codebase. It would also ruin typechecking, since in that case the state is an object that has specific attributes, while an Immutable Map, like a Python Dict, can have arbitrary keys; a subtle, but important semantic distinction that JS's object blurs. Perhaps the answer is having a helper func that converts back to a JS object whenever we query the store? Or would that be slow?

I suspect the solution involves some clever manipulations I don't know how to do. So we can reduce this Q as follows: What's the best way to immutably modify an Array or value stored within an object?

'ST
Jul 24, 2003

"The world has nothing to fear from military ambition in our Government."
There are a lot of ways to go about it.

First, for Immutable.js, you want the Record type, which gives you an immutable object with specific keys and forbids using unsupported keys. Records also support property access, so you don't need to use .get to access values (although you still can if you want).

Second, yes, you can have a selector (a function that queries the store) that returns a plain JS object rather than an immutable data structure. Some people strongly recommend keeping Immutable.js usage confined to Redux state and using plain Javascript elsewhere. There is definitely an advantage of portability for the non-Redux part of your app. That said, on my current project, we are happily using Immutable in a lot of places, not just reducers.

Performance of the selector function can be pretty bad if you return a naive state.meetings.find(...).toObject() because it will create a new object each time. This can cause a lot of unnecessary memory usage and React re-rendering if you are using Redux with React. Look into libraries like reselect or memoize the selector yourself with lodash. With the right selector memoization and the right React component update configuration, you can do immutable -> plain JS transformations in selectors with no real performance impact.

You're probably balking at the liberal use of spread operators to copy entire subobjects, but really, cloneDeep is doing all of that copying and more, just wrapped up in a pretty function. One option is to write a separate function next to your reducer that does all of the object spread stuff and returns the new state after doing some operation on "puck meetings." Then you'd have a specific but verbose updater function that you can call on one line in several of your "puck meeting" action handler cases.

Ultimately, though, I'd recommend a different state shape if you can accomplish it. Deeply nested state can lead to a lot of confusion for people new to Redux, which I think is happening in your case. It's also likely to lead to a massive reducer that handles dozens of actions that don't actually have any relation with one another.

I'd recommend Dan Abramov's (Redux creator's) video series Building React Applications with Idiomatic Redux to get some new ideas. In particular, I'd recommend these Redux-specfic videos: https://egghead.io/lessons/javascript-redux-normalizing-the-state-shape and https://egghead.io/lessons/javascript-redux-refactoring-the-reducers

I've had a lot of success going in directions like that and I've had a bit of heartache when nesting state.

Dominoes
Sep 20, 2007

Thanks for the detailed, on-point answer! Going to try those and think over which is the best approach.

ynohtna
Feb 16, 2007

backwoods compatible
Illegal Hen
^^^ Pro post from 'ST.

Dominoes posted:

The examples given show code that looks pretty obfuscated

Spread operators (and the other new bits of ES6 syntax) are going to become increasingly common, so getting familiar with them now is a good time investment if JS is a long-term thing for you.

All new syntax looks weird at first, innit. You'll bond with it soon enough. :)

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

The spread operator is one of the best new things in JS!

Anyway, I agree that you should strive as much as possible to keep your state flat.

Dominoes
Sep 20, 2007

Neat; looks just like * in Python.

Thermopyle posted:

Anyway, I agree that you should strive as much as possible to keep your state flat.
It's not too bad; the nesting's mostly due to the objs being serialized Django models.

Ie:

Layer 1 is to split between combined reducers
Layer 2 is a django model
Layer 3 is the fields property of the model (ie models are serialized with primary key, model type, then 'fields' object that has your actual fields. I'm not sure I agree with the way this is handled, but I'd rather go with the standard.)
Layer 4 is another model that's a foreignkey
layer 5 is the fields property of that sub/foreinkey module

I don't think there's a way around that.


edit: Tried out the spread approach... Not so bad! Examples:

JavaScript code:
// Adding to an array one layer down:
case 'addLine':
    // newState.lines.push(action.line)
    // return newState
    return {...state, lines: [...state.lines, action.line]}


// Adding to an object 2 layers down:
case 'addSchedule':
    // newState.schedules[action.date] = action.schedule
    // return newState
    return {...state, schedules: {...state.schedules, [action.date]: action.schedule}}
   
Example of a complete, basic reducer:
JavaScript code:
const reducer = (state=initialState, action: any) => {
    switch (action.type) {
        case 'addSchedule':
            return {...state, schedules: {...state.schedules, [action.date]: action.schedule}}

        case 'changeStart':
            return {...state, start: action.start}

        case 'changePerson':
            const activePk = state.activePerson != null ? store.getState().activePerson.pk : null
            if (activePk != action.person.pk) {
                return {...state, activePerson: action.person}
            }
            // We've toggled it off by clicking the already-active person.
            else {
                return {...state, activePerson: null}
            }

        default:
            return state
    }
}
Splitting statements like this across multiple lines was p confusing in the Zapier link. I love how the case statement in JS somehow avoids curly braces.

Dominoes fucked around with this message at 16:36 on May 6, 2017

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

You need to normalize your models to eliminate nesting and make things betterrer.

https://egghead.io/lessons/javascript-redux-normalizing-api-responses-with-normalizr

Dominoes
Sep 20, 2007

Thanks; going to have to look at that (Or reassess Immutable.js, which is designed to handle nesting). Here's what a nested case can look like... gross.


JavaScript code:
// We're pushing an item to state.meetings.fields.people.
// This code below is crap/boilerplate, since the same thing could be described as this pseudocode from line 2 on:
return pushIn(state, ['meetings', meeting == oldMeeting, 'fields', 'people'], action.person)

case 'addPuckMeeting':  // ie a puck is dropped in place
    oldMeeting = _.find(state.meetings, meeting => meeting.fields.number == action.number)
    newMeeting = {...oldMeeting, fields:{...oldMeeting.fields, people: [...oldMeeting.fields.people, action.person]}}
    updatedMeetings = [...state.meetings.filter(m => m.fields.number != action.number), newMeeting]
    return {...state, meetings: updatedMeetings}
Do y'all think there would be value in a module that provides helper funcs to generate operations like the above, but where you write code like the mutable ...or cloneDeep version? Immutable.js has updateIn, etc funcs; perhaps something like that, but for stock JS datastructures. Example API in the comments above.

Dominoes fucked around with this message at 19:54 on May 6, 2017

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Dominoes posted:

Thanks; going to have to look at that (Or reassess Immutable.js, which is designed to handle nesting). Here's what a nested case can look like... gross.

FWIW, normalizing doesn't really eliminate nesting. It just minimizes it.

Dominoes posted:

Do y'all think there would be value in a module that provides helper funcs to generate operations like the above, but where you write code like the mutable ...or cloneDeep version? Immutable.js has updateIn, etc funcs; perhaps something like that, but for stock JS datastructures.

Ehh, if you normalize then there's not usually much of a need.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Dominoes posted:

Neat; looks just like * in Python.

It's not too bad; the nesting's mostly due to the objs being serialized Django models.


Your app rarely wants it's data in the same shape it gets it from an API, so you should (almost) always plan on transforming / normalizing what you get back from every API call you make. Just make it a habit.

Dominoes
Sep 20, 2007

Thx. If I understand correctly, these are three separate concepts: Reducing nesting, keeping API data in a common format for related objects, and finding an elegant way to immutably update a sub-structure.

Turns out my data was already in a commonish format across 4 different types of models... Managed to cut my reducer function to a fraction of its size by combining cases!

Unrelated:
React could be viewed as a good example of one description of functional-programming: You describe the end-product rather than the steps needed to make it. I didn't understand that description after reading it in a Haskell tutorial, but this seems like a great example.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Dominoes posted:



Unrelated:
React could be viewed as a good example of one description of functional-programming: You describe the end-product rather than the steps needed to make it. I didn't understand that description after reading it in a Haskell tutorial, but this seems like a great example.

Check out Elm ( http://www.elm-lang.org ) for a "real" functional language that directly relates to building web app that didn't make my head hurt so much. Even if you never use it much, it is very instructive on the concepts you mention.

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.
Not a js question, but a question that people familiar with npm can answer: how do I add an image to the npm package's display of a markdown readme file?

The following attempts have all failed, showing the alt text instead of the image. The final one works on github's display of the repo, but not at npmjs.com, where the alt text is displayed. They all work inside of VSCode.

code:
![Example usage](./Screenshot.png)

<img src="Screenshot.png" alt="Example Usage"/>

<img src="Screenshot.PNG" alt="Example Usage"/>

<img src="./Screenshot.PNG" alt="Example Usage"/>
This is the sort of little thing in programming that drives me insaaaaaaane.

edit: So it seems that the npmjs.com rendering of Readme.md doesn't have access to the relative-path files. The answer (or, AN answer) here was:

code:
<img src="https://raw.githubusercontent.com/githubUserName/RepositoryName/master/Screenshot.PNG" alt="Example Usage"/>

Newf fucked around with this message at 23:47 on May 7, 2017

CodfishCartographer
Feb 23, 2010

Gadus Maprocephalus

Pillbug

necrotic posted:

Something to be aware of with setInterval is there's no guarantee it will run as often as you ask, and it is also possible for two invocations to overlap (if they take too long).

With animation especially you want to use requestAnimationFrame and use some math to determine where you are in time. Let me hack up a quick example.

edit: Here you go https://jsfiddle.net/o9wtwqrp/1. Could definitely be better, but I hope this helps get you going. You can think of requestAnimationFrame(callback) as if it was setTimeout(callback, 1000/60), though they are not exactly the same.

edit2: I should add that game logic should be handled using setTimeout in a similar manner, but definitely not requestAnimationFrame. Process the game in one "thread" and then update your UI only in requestAnimationFrame.

A few days late, but thanks so much for this! This works perfectly. I noticed you mentioned to not run game logic in requestAnimationFrame - why is that? Lumping the game functions into the requestAnimationFrame ensures that it updates exactly when the progress bar does. Using setInterval doesn't sync up correctly with the progress bar, and I'm not sure how to otherwise get setTimeout to trigger every x milliseconds until told to stop.

necrotic
Aug 2, 2005
I owe my brother big time for this!

CodfishCartographer posted:

A few days late, but thanks so much for this! This works perfectly. I noticed you mentioned to not run game logic in requestAnimationFrame - why is that? Lumping the game functions into the requestAnimationFrame ensures that it updates exactly when the progress bar does. Using setInterval doesn't sync up correctly with the progress bar, and I'm not sure how to otherwise get setTimeout to trigger every x milliseconds until told to stop.

There's a couple reasons. First, and most importantly, some browsers will not run requestAnimationFrame unless the tab is in the foreground. This means your game loop will stop entirely in those browsers. Secondly, and this is more of a case-by-case thing, if the callback takes more than ~16ms the update will be deferred until the next frame which will delay the animation and your game logic.

When running game logic and UI updates in separate "threads" you should avoid using the UI as any sort of state. You can have your game loop either update a property somewhere with what the progress b ar's new value should be, or instead save the state that the UI thread will then use to calculate the current value.

If you don't care about either of the two limitations of RAF then there's no reason to not do it all in the one "thread", but if it ever becomes a problem refactoring after-the-fact to the split approach can be a lot of work.

Sab669
Sep 24, 2009

Noon on Monday and I'm done for the week already :suicide: So this isn't really a specific question but just a bizarre issue with IE11 that I'm looking for suggestions on how to debug this better.

It's an ASP.NET MVC application which uses Telerik's KendoUI controls.

I've got a page which has 25 fields and 2 buttons. Button 1 opens a search screen, button 2 opens another screen with the "base" 25 fields plus an additional 30. This screen can also open up the aforementioned search screen.

We've found a bug which only happens in IE when you open that "advanced" popup, then from there load the search screen.

This search screen has 3 grids. One grid lists "primary" codes for the user to select (via a radio button). When they select a record, an ajax request is made to populate the two child grids. These child grids have check boxes to select records from. So a user can select up to 1 record from the parent radio button grid, and any number of records from the child grids.

When they've selected the code(s) they want, they can click a button on this search popup and it will fill in the textboxes on the screen which opened this search popup.

The bug is that in IE, you open the advanced screen, open the search, click a parent grid item and click select to feed it back to the form. Click another parent grid item, select... When you click on the 18th code, the browser becomes unresponsive / stops painting.

No error logs, no output to the console, nothing in the Profiler / UI Responsiveness​ tab / Network tab indicates a problem. Whether I debug via Visual Studio or IE's dev tools to step through the JS the issue doesn't really happen; it's only when you "normally" use the software.

I have absolutely no idea what could be causing this :(

Dominoes
Sep 20, 2007

Yo dudes. React Class-based comp question. I've been working on an app using functional components, but now have a comp that needs to track a var that's not part of the main state. I made it a class-based component using This guide. Is there a way around code like this?:

JavaScript code:
    constructor(props) {
        super(props)
        this.state = {number: this.props.line.fields.number}

        this.handleChange = this.handleChange.bind(this)
        this.handleSubmit = this.handleSubmit.bind(this)
    }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    //
  }

IDK what it does, but it doesn't appear to describe anything, other than the line ' this.state = {number: this.props.line.fields.number}' defines a default value for our field, and the handleSubmit function processes the data; ie commit it to the overall state Is there a way around this syntax for managing form values?

Dominoes fucked around with this message at 20:02 on May 8, 2017

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Sab669 posted:

Noon on Monday and I'm done for the week already :suicide: So this isn't really a specific question but just a bizarre issue with IE11 that I'm looking for suggestions on how to debug this better.

It's an ASP.NET MVC application which uses Telerik's KendoUI controls.

I've got a page which has 25 fields and 2 buttons. Button 1 opens a search screen, button 2 opens another screen with the "base" 25 fields plus an additional 30. This screen can also open up the aforementioned search screen.

We've found a bug which only happens in IE when you open that "advanced" popup, then from there load the search screen.

This search screen has 3 grids. One grid lists "primary" codes for the user to select (via a radio button). When they select a record, an ajax request is made to populate the two child grids. These child grids have check boxes to select records from. So a user can select up to 1 record from the parent radio button grid, and any number of records from the child grids.

When they've selected the code(s) they want, they can click a button on this search popup and it will fill in the textboxes on the screen which opened this search popup.

The bug is that in IE, you open the advanced screen, open the search, click a parent grid item and click select to feed it back to the form. Click another parent grid item, select... When you click on the 18th code, the browser becomes unresponsive / stops painting.

No error logs, no output to the console, nothing in the Profiler / UI Responsiveness​ tab / Network tab indicates a problem. Whether I debug via Visual Studio or IE's dev tools to step through the JS the issue doesn't really happen; it's only when you "normally" use the software.

I have absolutely no idea what could be causing this :(

Normally when something breaks in IE < 12 unless I have the dev tools open, I assume someone tried to log something to the console somewhere, or am I misunderstanding and it goes unresponsive if the debugger is open and there are just too many items checked? If it's that, try hitting the pause button - it should halt JS execution somewhere in what I assume is an infinite loop and you can check the stack. Thing is, I thought 11 still had the execution counter, so I'm not sure why it wouldn't pop up the 'Do you wan to kill running JS' modal.

ddiddles
Oct 21, 2008

Roses are red, violets are blue, I'm a schizophrenic and so am I

Dominoes posted:

Yo dudes. React Class-based comp question. I've been working on an app using functional components, but now have a comp that needs to track a var that's not part of the main state. I made it a functional component using This guide. Is there a way around code like this?:

JavaScript code:
    constructor(props) {
        super(props)
        this.state = {number: this.props.line.fields.number}

        this.handleChange = this.handleChange.bind(this)
        this.handleSubmit = this.handleSubmit.bind(this)
    }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    //
  }

IDK what it does, but it doesn't appear to describe anything, other than the line ' this.state = {number: this.props.line.fields.number}' defines a default value for our field, and the handleSubmit function processes the data; ie commit it to the overall state Is there a way around this syntax for managing form values?

this.state sets the default state for that component, and you have to do that stupid this.method = this.method.bind(this) workaround if you want to pass that method into any child components that class based component will have, or you can do it when you pass the method into any child components, like this.

code:
<SomeChildComponent methodToPass={ this.methodImPassing.bind(this) } />
Putting it in the class constructor makes it easier if you are passing methods to multiple child components.

As far as form fields are concerned, the way I learned it was to bind form field values to either the form components state or it's parents state, using an onChange hook on the form field to update the state, which passes the new value to the form field.

ddiddles fucked around with this message at 20:01 on May 8, 2017

CodfishCartographer
Feb 23, 2010

Gadus Maprocephalus

Pillbug

necrotic posted:

There's a couple reasons. First, and most importantly, some browsers will not run requestAnimationFrame unless the tab is in the foreground. This means your game loop will stop entirely in those browsers. Secondly, and this is more of a case-by-case thing, if the callback takes more than ~16ms the update will be deferred until the next frame which will delay the animation and your game logic.

When running game logic and UI updates in separate "threads" you should avoid using the UI as any sort of state. You can have your game loop either update a property somewhere with what the progress b ar's new value should be, or instead save the state that the UI thread will then use to calculate the current value.

If you don't care about either of the two limitations of RAF then there's no reason to not do it all in the one "thread", but if it ever becomes a problem refactoring after-the-fact to the split approach can be a lot of work.

Ahh, good to know! I rejiggered things so that it resets the bar's value when the game logic ticks over, so if there's a desync between how often a game logic tick "should" be happening and when it actually does, it's pretty much not noticeable. Stuff's working exactly how I'd like it to now, Thanks for the help!

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself
Nevermind

teen phone cutie fucked around with this message at 20:20 on May 8, 2017

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Dominoes posted:

Yo dudes. React Class-based comp question. I've been working on an app using functional components, but now have a comp that needs to track a var that's not part of the main state. I made it a class-based component using This guide. Is there a way around code like this?:

JavaScript code:
    constructor(props) {
        super(props)
        this.state = {number: this.props.line.fields.number}

        this.handleChange = this.handleChange.bind(this)
        this.handleSubmit = this.handleSubmit.bind(this)
    }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    //
  }

IDK what it does, but it doesn't appear to describe anything, other than the line ' this.state = {number: this.props.line.fields.number}' defines a default value for our field, and the handleSubmit function processes the data; ie commit it to the overall state Is there a way around this syntax for managing form values?
If you're willing to use stage-2 transforms (or just transform-class-properties) with babel you can do:

JavaScript code:
class Bork {
  handleChange = (event) => this.setState({value: event.target.value});
  // blah blah blah
}
Arrow functions bind this implicitly.

Thermopyle fucked around with this message at 23:25 on May 8, 2017

Dominoes
Sep 20, 2007

Thanks loads, ddiddles and Therm. You guys are true bros.

Got another one. I switched my app over to React entirely, and am running into trouble with drag and drops. Before used JQuery UI; straightforward. Switched to React DnD, which is a very popular and apparently full-up package. Unfortunately, it's missing a critical feature; being able to scroll (ie mwheel or keyboard) while dragging. According to This thread, it's a limitation in the HMTL5 dnd backend, and the only direct fix is to wait until they implement more back ends.

Someone in that thread made a https://github.com/azuqua/react-dnd-scrollzone workaround module called react-dnd-scrollzone, which allows auto-scrolling when a draggable is at the top/bottom of an element. Unfortunately, it uses its own sub-scrollwindow, which is not what I'm looking for. I'm working on implementing my own component to do the same, but for the whole window. I've set up fixed divs on the top and bottom that only appear when you're dragging something, so it doesn't screw with the page otherwise. Having trouble implementing the scroll logic through. Ie using normal JS, or a library called react-scroll, I can get the window to scroll to specific places when you drag something over the divs, but not to initiate start or stop scrolling. I can listen for start/stop scrolling using the component, but can't actually initiate or stop the scrolling when these fire - any ideas? Here's what I've got so far... I suspect it just needs a littler finisher-offer. I plan to post this to NPM when it's done; I think this is a more general solution that the dnd-scrollzone fix I posted about.

This chunk of code is attempting to do it with setInterval scrolling. It currently scrolls 1px, then stops, rather than continuing. I can post the react-scroll code to, which works as advertised, but doesn't appear to be able to stop the scrolling at will; it just scrolls to an element.
JavaScript code:
let scrolling

@DropTarget(drag.ItemTypes.PUCK, drag.slotTarget, drag.collectSlot)
class SubScroller extends React.Component<any, any> {
    // Class component for React-DND decorator support.
    render() {
        const { type, enabled, height, connectDropTarget, isOver } = this.props

        // Temp diagnostic colors. Non-0 opacity for testing as well.
        const backgroundColor = isOver ? 'yellow' : 'blue'
        // Drag a fixed, invisible box of custom height at the top, and bottom 
        // of the window. Make sure to show it only when dragging something.
        const style: any = {position: 'fixed', backgroundColor: backgroundColor,
            height: height, width: '100%', opacity: .2, zIndex: 999}

        if (type == 'top') {
            style['top'] = 0
            style['backgroundColor'] = 'orange'
        }
        else if (type == 'bottom') {
            style['bottom'] = 0
            style['backgroundColor'] = 'pink'
        }

        if (isOver == true) {
        // Start scrolling.
            if (type == 'top') {
                scrolling = setInterval(window.scrollBy(0, 1), 10)
                style['backgroundColor'] = 'yellow' // temp diagnostic
                //pseudocode: startScrolling('down', speed) 
            }
            else if (type == 'bottom') {
                scrolling = setInterval(window.scrollBy(0, -1), 10)
                style['backgroundColor'] = 'yellow'  //  temp diagnostic
               //pseudocode: startScrolling('up', speed) 
            }
        }
        else {
            // Stop scrolling.
            clearInterval(scrolling)
            // Pseudocode: stopScrolling()

        }
        // Hide the element if not enabled, so it doesn't interfere with clicking things under it.
        if (enabled == true) {
            return connectDropTarget (
                <div style={style} />
            )
        }
        else {
            return <div />
        }
    }
}


const Scroller = ( {enabled=true, height=100, speed=10} ) => (
    // Parent scrolling element; set up a subscroller at the top of the page
    // for scrolling up; one at the botton for scrolling down.
    <div>
        <SubScroller type="top" enabled={enabled} height={ height }/>

        <SubScroller type="bottom" enabled={enabled} height={ height } />
    </div>
)
I suspect the solution lies in modifying the code under the //start scrolling and //stop scrolling comments, since the div and triggers work as expected. Related: Is implicit truth OK? Haven't found an answer on it. My IDE doesn't offer a simplification like it does in python. Ie can if (myBool == true) can be replaced by if (myBool)

If anyone has another idea of how to make drag+drop work in react if you need to drag somewhere not on-screen, I'm all-ears. I think my proposed fix would be almost as good as not blocking mouswheel scroll, if I can get it working. If this doesn't work, I'm going to have to figure out how to hack Jquery-ui drag+drop into React.


edit: Solved with advice elsewhere: Changed the the scroll start code to
JavaScript code:
const direction = type == 'top' ? -speed : speed
// Scroll speed pixels every millisecond.
scrolling = setInterval(() => {
    window.scrollBy(0, direction)
}, 1 )
Mozilla link confirming that implicit truth works similar to how it does in python.

Dominoes fucked around with this message at 13:33 on May 13, 2017

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.
Any suggestions on how I should go about parsing a typescript project to get, for example, a tree structure of class inheritance / composition, or a list of classes implementing a particular interface?

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.

Newf posted:

Any suggestions on how I should go about parsing a typescript project to get, for example, a tree structure of class inheritance / composition, or a list of classes implementing a particular interface?

If you can export the definition file to cut out the implementation noise, then you could try and get an AST out of that definition file. From there it's surely just crunching the AST as you want to yeah?

edit: The compiler has an API so I'd definitely read this over and try using the AST concepts: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API

Maluco Marinero fucked around with this message at 01:20 on May 15, 2017

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.

Maluco Marinero posted:

edit: The compiler has an API so I'd definitely read this over and try using the AST concepts: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API

Ah, here we go. Thank you.

huhu
Feb 24, 2006
I'm trying to write my own ParsleyJS validator and I'm a bit lost. I want to check that the date is only in the future. I'm able to submit without errors.


code:
<td class="col0"><label for="date">Enter a future date</label></td>
<td class="col1"><input type="date" id = "date" data-parsley-future-date=""></td>

<script>
window.Parsley
  .addValidator('futureDate', {
    requirementType: 'date',
    validateString: function(value, requirement) {
      var now = new Date();
      var selctedDate = new Date(value);
      return selectedDate > now; 

    },
    messages: {
      en: 'This date must be in the future',
    }
  });
</script>

Dogcow
Jun 21, 2005

huhu posted:

code:

var selctedDate = new Date(value);
return selectedDate > now; 

Typo in your variable name.

ROFLburger
Jan 12, 2006

I would have reread that a hundred times and not noticed that typo

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

ROFLburger posted:

I would have reread that a hundred times and not noticed that typo

Only other people can spot your typos. Using ctrl-p in VIM while typing is wonderful. I only ever type a variable name once. Because if I have to type it more than that, you bet I'm gonna screw it up.

100 degrees Calcium
Jan 23, 2011



I have a feeling this is gonna be pretty remedial for most of you, but I'm struggling with this task in jQuery.

I have a form that will need to be able to accept an unknown number of file inputs. The form begins by displaying one, but I wrote a script that should add a new one whenever the value of an existing one changes; this way, there should always be room for "one more" file in the form.

Here's what I'm working with

code:
...
<td id="advanced-file-upload-cell">
    <input type="file" class="advanced-file-upload"/>
</td>
...
<script type="text/javascript">
    $(".advanced-file-upload").change(function () {
        var newInput = "<br /><input type='file' class='advanced-file-upload' />";
        $("#advanced-file-upload-cell").append(newInput);
    });
</script>
In theory, this should detect whenever an element with the class advanced-file-upload changes and append a new file input with that type into the cell. This works with the original file input, no matter how many times the value changes (which is another problem I have to solve after this), but the new inputs that are generated by my script do not exhibit that behavior. I double-checked and they are definitely being generated with the correct class name.

100 degrees Calcium fucked around with this message at 22:09 on May 15, 2017

huhu
Feb 24, 2006
That typo was actually from me making my code snippet more organized for that post. Whelp. Somehow figured it out anyways so there's that.

Video Nasty
Jun 17, 2003

100 degrees Calcium posted:

I have a feeling this is gonna be pretty remedial for most of you, but I'm struggling with this task in jQuery.

I have a form that will need to be able to accept an unknown number of file inputs. The form begins by displaying one, but I wrote a script that should add a new one whenever the value of an existing one changes; this way, there should always be room for "one more" file in the form.

Here's what I'm working with

code:
...
<td id="advanced-file-upload-cell">
    <input type="file" class="advanced-file-upload" />
</td>
...
<script type="text/javascript">
    $(".advanced-file-upload">.change(function() {
       var newInput = "<br /><input type='file' class='advanced-file-upload' />";
	$("#advanced-file-upload-cell").append(newInput);
    });
</script>
In theory, this should detect whenever an element with the class advanced-file-upload changes and append a new file input with that type into the cell. This works with the original file input, no matter how many times the value changes (which is another problem I have to solve after this), but the new inputs that are generated by my script do not exhibit that behavior. I double-checked and they are definitely being generated with the correct class name.

Issue could be due to targeting the className that all of your elements share; oh, I see that purpose now. I think the issue is due to you creating new elements without repainting the DOM so jQuery doesn't know how to handle the new inputs that were inserted.

e: :doh: Lumpy caught the obvious typo.

Video Nasty fucked around with this message at 20:29 on May 15, 2017

100 degrees Calcium
Jan 23, 2011



What you're saying makes sense. I looked it up and it appears that window.getComputedStyle() forces reflow, so I threw that at the end of my script. Sadly, no change in behavior aside from a bit of slowdown upon changing the value of the original file input.

I'm thinking about just making it so that there is no file input until the user clicks a button that triggers the event in my code. It adds a step to adding files, but it makes the behavior easier for me to control.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

100 degrees Calcium posted:

What you're saying makes sense. I looked it up and it appears that window.getComputedStyle() forces reflow, so I threw that at the end of my script. Sadly, no change in behavior aside from a bit of slowdown upon changing the value of the original file input.

I'm thinking about just making it so that there is no file input until the user clicks a button that triggers the event in my code. It adds a step to adding files, but it makes the behavior easier for me to control.

TYPO:

code:
$(".advanced-file-upload">
Not sure if that's in your code or not, but if it is, that's probably why it no work. Adding an element should re-draw, so you don't need the computed style thing.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Typos: one of the reasons IDEs are the best. :colbert:

Just kidding (sort of). I assume you can get spellcheck plugins for the popular text editors that can spellcheck "words" in the various popular variable naming schemes? (camelcase, snakecase, underscores, etc)

JavaScript code:
function ha() {
  var selctedDate = new Date(value);
  return selectedDate > now; 
}
PyCharm warns me on "selcted" being misspelled and "return selectedDate " being unresolved.

Adbot
ADBOT LOVES YOU

100 degrees Calcium
Jan 23, 2011



Lumpy posted:

TYPO:

code:
$(".advanced-file-upload">
Not sure if that's in your code or not, but if it is, that's probably why it no work. Adding an element should re-draw, so you don't need the computed style thing.

I wish I could say that was it, but this was actually my failure in re-typing the code when I should have copied-pasted. I don't even know why I did that.

I think that was the only typo I created here, but just in case I've edited my post with the code actually copied.

I'm really flailing with this one, I don't even have a theory at this point, except that possibly adding the element by including the HTML in a string and simply appending the string to a cell somehow doesn't count as adding an element as far as re-draw is concerned. But forcing the re-draw isn't working and I don't really know a better/cleaner way.

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