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
CPColin
Sep 9, 2003

Big ol' smile.

sunaurus posted:

I guess I'm just overthinking it and the easiest way of saying it is just "do all the things in a single loop"

"Quit loving around" is also acceptable.

Adbot
ADBOT LOVES YOU

Munkeymon
Aug 14, 2003

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



You could say the operations should be more tightly/highly coupled

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Yeah I'm not sure there's a specific term for it, you'd probably just describe it as combining functions into a single iteration, consolidation, something like that

If it helps any this is similar to function composition, where you chain a bunch of functions together and just pass in your input stuff once, so it passes through the function chain and the output is the result of running all the functions on the input. This could involve multiple iterations (run the 1st function on everything, run the 2nd function on the results of that...) but the compiler could be smart and run everything on one element at a time, or you could do that explicitly with lazy evaluation

I think Stream Processing generally describes this one-at-a-time approach? (because a stream can be arbitrarily long, so you can't iterate over "all the things" for each function in turn)

raminasi
Jan 25, 2005

a last drink with no ice
It's called loop fusion.

chglcu
May 17, 2007

I'm so bored with the USA.
In Visual Studio 2019, is there any way to hide the little code cleanup "No issues found" thing in the lower left of the editor window? It keeps catching my eye and every time it pisses me off more and more.

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

chglcu posted:

In Visual Studio 2019, is there any way to hide the little code cleanup "No issues found" thing in the lower left of the editor window? It keeps catching my eye and every time it pisses me off more and more.

post-it

Happy Thread
Jul 10, 2005

by Fluffdaddy
Plaster Town Cop
I have two objects that are too tightly coupled. I want a better organization.

Where does the below kind of "options object" go in an OO framework?

Suppose that an object of type A is always accompanied by another object that is essentially "options for the A object to use".

function( A, optionsForAnA )

They're kept separate because each A is expensive to make, but a list of its options is cheap to make. The application demands calling upon your A very frequently with different sets of options each time, so you'd like to save each option set in an object and re-use.

They're tightly coupled. Right now, my optionsForAnA can't exist with out an A instantiating it, to populate it with defaults appropriate for its subtype (due to many possible subclasses of A). So even if a static function of A applies these defaults, optionsForAnA cannot stand alone without class A. The dependency goes both ways: an A can't exist without an optionsForAnA, because it needs those specifics when it is called.

What is a better organization?

Linear Zoetrope
Nov 28, 2011

A hero must cook
It seems like the problem isn't the fact that you have an Options class per se. It's mostly just something to prevent every function from having 20 arguments. It's the squirliness of each subtype having its own default set that seems to be the problem.

A lot of the ways to handle this heavily depend on the language you're using, but one spitball is to keep the Options struct, but make it a member of of the A base class, and have two import_options/export_options methods that let you easily back up and restore the current options set.

Another option I've used is to, instead of functions, have a higher level Algorithm class that holds both an A and an A option, as well as the current context of the computation. When you construct the Algorithm with only an A, it automatically populates the options fields with some get_default, or with an existing option struct. That way you don't need to pass it through every time.

It also does somewhat depend on what you're doing, though. The answer for doing, say, a parameter search algorithm where the Options struct is the search space is going to be different from, say, handling user data where each user has a different set of options.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Aren't they inherently coupled though? What's the problem you're running into with the way you're currently doing it?

e- if it's the fact you want to pass both things into that function, but you can't create either thing without having the other, you could make the A class responsible for producing the Options class

If you have a function in A that spits out a default Options object, you could override that in any subclasses of A that need a different set of defaults. A's constructor can just call its own GetOptions function to initialise itself, so you don't need to create an Options object externally and pass it in

baka kaba fucked around with this message at 08:23 on Apr 14, 2019

Happy Thread
Jul 10, 2005

by Fluffdaddy
Plaster Town Cop
For what it's worth I think my current solution happens to be pretty elegant -- it only requires you to hold onto an OptionsForA, commanding it to do its thing, without needing to constantly juggle an A along with it. That's because it contains a reference back to the A that made it, and in that way maybe serves as the "Algorithms" wrapper you propose. The only problem is that this design is hard to explain and that makes it ugly.

I'll tell you the specifics since it comes down to those.

It's JavaScript, and a 3D graphics application. The class in question is Shader. A Shader is expensive to make (it is an entire subprogram that gets sent to the graphics card, and tells it how to color shapes in).

Every moment of animation, hundreds of objects are drawn, and with each of these calls to draw() something, the Shader must perform its action. When it performs it, it passes in a lot of options to the graphics card (which I have wrapped as an Options object --- called a "Material"). A Material is cheap to make and just wraps numbers, except for the reference to the Shader itself, so that in practice one only needs to pass the Material into draw() in order for the Shader action to happen with the correct Material options.

In my current design, many possible subclasses of Shader exist, to accommodate the infinite different possible programs that can be passed to the graphics card (and different JavaScript each of them needs for communication). For each of these subclasses, a different set of default properties for a Material is appropriate. Therefore, a Material cannot exist without a particular Shader subclass telling it which members it should include -- although we may later override the numbers stored in those members. Either way, a Material gets saved and re-used a lot.
Likewise, a Shader subclass cannot exist without a Material, because it needs to pass its specific material data to the graphics card every time it draws.

This works, but it makes for a very messy class diagram. I'm trying to draw one for students and I don't want it to be too painful to read.

Happy Thread fucked around with this message at 08:23 on Apr 14, 2019

RPATDO_LAMD
Mar 22, 2013

🐘🪠🍆
So the A objects all know what their "default" options should be anyways, since they use those to initialize the options class, right?
Just make all the values in the optionsForAnA nullable, then have the A class use its own default value for fields that are null in the options.
Then rather than needing to populate the options class with appropriate defaults on construction, you just populate it with nulls, which'll work universally for any A.

Happy Thread
Jul 10, 2005

by Fluffdaddy
Plaster Town Cop

RPATDO_LAMD posted:

So the A objects all know what their "default" options should be anyways, since they use those to initialize the options class, right?
Just make all the values in the optionsForAnA nullable, then have the A class use its own default value for fields that are null in the options.
Then rather than needing to populate the options class with appropriate defaults on construction, you just populate it with nulls, which'll work universally for any A.

Now that's a good idea. So, I'd fill in the defaults later in the process, during draw(), if they're blank rather than needing them right away when a Material is constructed.

One issue is there's no guideline for what kind of properties I might need. So there's no "master list" of options I could make that each possible Shader only sets a subset of the properties of. The user could program any Shader that needs any possible settings. (In practice this happens in graphics; arbitrary shader programs have been created that send all sorts of non-compatible variables over to the graphics card memory and there's no predicting what kinds of flags/settings/numbers will be present).

Your suggestion might nonetheless be the fix I'm looking for though.

What I think your idea means is I would make a Material that is just an object wrapping the particular Shader I want, plus any non-defaults I'd like to include. I'd pass that into draw(), which would then call the Shader with those options, and any missing options would be filled in by the specific Shader type.

code:
const material = { shader, color = [ 0,1,0,1], ambient = .3 };    // Leave out some other options
box.draw( material );			// Inside here the missing options get filled in with defaults
Not bad!

A Material no longer needs to be instantiated from inside a Shader. Significantly less awkward.

Happy Thread fucked around with this message at 09:03 on Apr 14, 2019

Happy Thread
Jul 10, 2005

by Fluffdaddy
Plaster Town Cop
(Sorry for all the edits, took a while for it to sink in)

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

I think the idea is that the Material class is the data, so the Shader doesn't actually store those values itself - it just references the Material directly?

Yeah I'd probably just make the Shader responsible for producing Material objects, each subclass can define its own default Material and return that, and it can initialise itself with that too. That way you have a straight dependency - you can create Shaders without supplying a Material, but if you want a Material, you need a Shader to draw it from (so you always get something valid)

I dunno if you could do anything like generics where ShaderType produces a Material<ShaderType> so you can only ever pass in the correct Material, but maybe all the Materials have the same parameters just with different values?

e- I'm slow

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

Dumb Lowtax posted:

For what it's worth I think my current solution happens to be pretty elegant -- it only requires you to hold onto an OptionsForA, commanding it to do its thing, without needing to constantly juggle an A along with it. That's because it contains a reference back to the A that made it, and in that way maybe serves as the "Algorithms" wrapper you propose. The only problem is that this design is hard to explain and that makes it ugly.

I'll tell you the specifics since it comes down to those.

It's JavaScript, and a 3D graphics application. The class in question is Shader. A Shader is expensive to make (it is an entire subprogram that gets sent to the graphics card, and tells it how to color shapes in).

Every moment of animation, hundreds of objects are drawn, and with each of these calls to draw() something, the Shader must perform its action. When it performs it, it passes in a lot of options to the graphics card (which I have wrapped as an Options object --- called a "Material"). A Material is cheap to make and just wraps numbers, except for the reference to the Shader itself, so that in practice one only needs to pass the Material into draw() in order for the Shader action to happen with the correct Material options.

In my current design, many possible subclasses of Shader exist, to accommodate the infinite different possible programs that can be passed to the graphics card (and different JavaScript each of them needs for communication). For each of these subclasses, a different set of default properties for a Material is appropriate. Therefore, a Material cannot exist without a particular Shader subclass telling it which members it should include -- although we may later override the numbers stored in those members. Either way, a Material gets saved and re-used a lot.
Likewise, a Shader subclass cannot exist without a Material, because it needs to pass its specific material data to the graphics card every time it draws.

This works, but it makes for a very messy class diagram. I'm trying to draw one for students and I don't want it to be too painful to read.

It sounds like you’re murdering your cache with great prejudice. I’m going to need to unteach your students about this in a few years.

You should probably think about what your data layout looks like to the machine if you care about perf.

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

leper khan posted:

It sounds like you’re murdering your cache with great prejudice. I’m going to need to unteach your students about this in a few years.

You should probably think about what your data layout looks like to the machine if you care about perf.

Got any actual specific pointers here or just want to look smug and superior without contributing?

Thermopyle
Jul 1, 2003

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

What are you using to organize and track code snippets?

I've kept them in various places over the years, including the tools built-in to whatever IDE, but then I eventually move on to another editor/IDE.

I got tired of moving them from system to system, so now I usually just search through past projects to find what I need (not always successful in finding it this way either) and that seems kind of dumb...no?

Thermopyle fucked around with this message at 18:09 on Apr 14, 2019

chutwig
May 28, 2001

BURLAP SATCHEL OF CRACKERJACKS

Thermopyle posted:

What are you using to organize and track code snippets?

I've kept them in various places over the year, including the tools built-in to whatever IDE, but then I eventually move on to another editor/IDE.

I got tired of moving them from system to system, so now I usually just search through past projects to find what I need (not always successful in finding it this way either) and that seems kind of dumb...no?

If you use a Mac, Dash has built-in snippet organization, and I think it can be set up to sync to Dash on iOS as well.

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

carry on then posted:

Got any actual specific pointers here or just want to look smug and superior without contributing?

I already gave the tip. If you took the time to read and comprehend my short post, you would see that. Look at and reason about your data layout and optimize for cache misses.

If you want another pointer, indirect fewer pointers.

Dr. Stab
Sep 12, 2010
👨🏻‍⚕️🩺🔪🙀😱🙀

leper khan posted:

I already gave the tip. If you took the time to read and comprehend my short post, you would see that. Look at and reason about your data layout and optimize for cache misses.

If you want another pointer, indirect fewer pointers.

I'm happy you got to feel like you brutally owned that noob, but that's actually not something you can do at the same time that you're helping them. Pick one of the two.

Happy Thread
Jul 10, 2005

by Fluffdaddy
Plaster Town Cop

leper khan posted:

I already gave the tip. If you took the time to read and comprehend my short post, you would see that. Look at and reason about your data layout and optimize for cache misses.

If you want another pointer, indirect fewer pointers.

Generally someone has few Shaders and lots of Materials so the pointer indirections to Shaders are unlikely to cache miss. In any case, we're talking about very low quantities, and performance profiling suggests that the performance importance this whole section of a graphics program simply pales in comparison to the actual slow parts of a graphics program. Meanwhile, caching is very important when considering the slow CPU-to-GPU data pipeline. You especially don't want to issue duplicate commands to send a number over (due to re-using a Material twice in a row, or having two Materials share similar properties). To prevent that I'm having the Shader class maintain a big dictionary of all variables that exist GPU-side, complete with their last known values, so the Shader can compare against that first instead of sending any unnecessary numbers down the slow GPU pipeline.

LongSack
Jan 17, 2003

chglcu posted:

In Visual Studio 2019, is there any way to hide the little code cleanup "No issues found" thing in the lower left of the editor window? It keeps catching my eye and every time it pisses me off more and more.

Almost positive I saw something in Tools | Options to turn it off. Pretty sure it was in editor settings

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

leper khan posted:

I already gave the tip. If you took the time to read and comprehend my short post, you would see that. Look at and reason about your data layout and optimize for cache misses.

If you want another pointer, indirect fewer pointers.

I truly and genuinely feel sorry for your students. They must wonder what it's like to have a professor instead of an rear end.

e: nah, there's no way you're anything above a graduate TA.

Happy Thread
Jul 10, 2005

by Fluffdaddy
Plaster Town Cop
I was assuming they meant they worked in industry and would have to teach better software design practices than this as soon as my students enter the workforce. Because there's no way anyone working in a school would care so deeply about how some obscure engine performs that students might be using for their homework.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Objects having a draw() function is the wrong way to architect a renderer -- you want the ability to sort your draw calls independently of the scene graph, and objects might render in multiple passes. You want to do all your data uploads to the GPU in one pass at the start of a frame, rather than the uploads happening at draw time. Unfortunately, that means you need UBOs and WebGL2, which might be unsuitable in your case.

Also, the shader/material are not the entirety of your draw state -- there's also the other pipeline state (blend, depth, rast, etc.) and vertex inputs.

Happy Thread
Jul 10, 2005

by Fluffdaddy
Plaster Town Cop

Suspicious Dish posted:

Unfortunately, that means you need UBOs and WebGL2, which might be unsuitable in your case.

Yeah sadly :( I've made the decision to not lock out iPhone users from being able to play my engine's games and view its animation-heavy sites. They lack WebGL2 support and unfortunately it looks like Apple has no plans at all for changing this anytime soon.

Suspicious Dish posted:

Also, the shader/material are not the entirety of your draw state -- there's also the other pipeline state (blend, depth, rast, etc.) and vertex inputs.

Yeah I was simplifying, I issue each draw command with information that's split into two categories: Material (quantities relevant to just this shape/draw call) and Program_State (longer-term quantities relevant to several draw calls). Both Material and Program_State get passed into draw(). Stuff like camera and light state and drawing settings would go into Program_State, as well as some shader options that should affect the whole scene at once if flipped (like if one has a "debug mode" defaulting to simpler colors). Meanwhile the vertex inputs live in a "Shape" of some subtype. Each subtype generates its own vertices out of any custom arrays the user wants. These shapes are what own the .draw() function in my model just because, like you pointed out, in WebGL1 there's a 1-to-1 correspondence between a GPU draw call and a single new shape appearing onscreen.

Happy Thread
Jul 10, 2005

by Fluffdaddy
Plaster Town Cop
Do you know of anyone who's written about any standard ways to organize WebGL code? It seems like everybody pretty much rolls their own organization, or uses one of the major open source wrappers that already does it. Considering OpenGL at large, the knowledge of how best to organize it seems mostly wrapped up in big commercial suites for graphics like Maya that you can't just crack open and read in a day, not that its source code would be anywhere near small enough to accompany a textbook or guide about how to organize WebGL like what I'm thinking of. I'd like to make such a guide once I learn enough.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Yes, I told you the modern approach to designing a renderer: draw calls that can be sorted and executed independently outside of any context. OpenGL is a terrible API that teaches you bad ideas about graphics and GPUs. Stray far from its design ideas and truly understand what the driver is doing. e.g. Did you know that calling glEnable(GL_BLEND) will recompile shaders on iPhones and most other mobile devices?

As a quick rundown, your draw calls should not be generated from shapes/objects/shaders/materials, but from passes. Passes take as inputs your entire scene graph, decide which objects it wants to render, what shaders they should use, and renders them. There are many, many passes in a modern game, but examples might be: depth prepass, G-Buffer, shadow map (one per light, including hierarchical frustum shadows for your directional), opaque color, AA resolve, transparent color, decals, UI, postfx.

Each pass will render some subset of objects, or even none at all for a purely postfx pass, and there's a shared understanding between the pass and the object's shading itself -- this sort of common shading API is commonly known as a "material system" -- the shader needs to be written for each shape for all passes. You can see this as the output channels in the shader graphs of popular engines. The pass itself uses these outputs to determine how it will render and shade objects.

Putting draw() on the Shape and relying on the driver to copy per-draw data is an antipattern that takes people a long time to get out of, and will hurt you more than it will help you when switching to modern APIs. When you start moving to WebGPU, you are going to need the scene's data uploaded at the start of each frame, in non-overlapping buffers. Doing that is tricky if you have your scene graph tied directly to your draws.

I could go on for a long time, but since I doubt anybody cares I'll stop here. Let me know if you need more help. There's also a good number of documentation about other modern renderer architecture; e.g. Unreal's 4.22 refactor, SEED's Halcyon, Unity's Scriptable Render pipeline.

I have my own high-level platform layer and renderer modeled after Metal/WebGPU/other game renderers I've worked on. I've made my own design decisions for my own renderer based on known tradeoffs in my projects, and I have revised the APIs a lot over time. These tradeoffs might not apply to you.

https://github.com/magcius/noclip.website/blob/master/src/gfx/platform/GfxPlatform.ts
https://github.com/magcius/noclip.website/blob/master/src/gfx/render/GfxRenderer.ts

LongSack
Jan 17, 2003

LongSack posted:

Almost positive I saw something in Tools | Options to turn it off. Pretty sure it was in editor settings

Tools -> Options -> Text Editor -> General -> uncheck "Show file health indicator"

chglcu
May 17, 2007

I'm so bored with the USA.

LongSack posted:

Tools -> Options -> Text Editor -> General -> uncheck "Show file health indicator"

Awesome, thanks. Missed that multiple times.

Sylink
Apr 17, 2004

I'm not good and trying to make a class do a thing in python.

So I have a class like this:

code:

class Car(name,model):
    def __init__(self):
         ....

And I'd like to take a list of names/models and generate a list of objects. That goes just fine, however its obviously a normal list so you can only see that its an object and access it via an indice.

So you get a list like:

[<OBJECT>,<OBJECT>] etc

Is there a better way to do this so you can easily see basic info about each object at first glance in the list or would you always have to iterate over a list of object attributes?

I guess it doesn't matter since the program would iterate anyway but was just a detail bothering me as to whether lists of objects like this are ok.

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
Do you want a nice display when you print the list? If that's the case, you need to override the __repr__ function. For example:
Python code:
class MyObj(object):
  def __init__(self, a, b):
    self.a = a
    self.b = b
  def __repr__(self):
    return '<MyObj a=%s, b=%s>' % (self.a, self.b)

DoctorTristan
Mar 11, 2006

I would look up into your lifeless eyes and wave, like this. Can you and your associates arrange that for me, Mr. Morden?
On an unrelated note, you currently have class Car inheriting from two other classes, name and model:

code:

class Car(name,model):
    def __init__(self):
         ....

This probably isn’t what you want to do; if you want to express “a Car has a name and a model” then the usual approach would be to make these properties of a Car and set their values when constructing a Car object:

code:

class Car(object):
    def __init__(self, name, model):
        self.name = name
        self.model = model
         ...

DoctorTristan fucked around with this message at 09:42 on Apr 16, 2019

Sylink
Apr 17, 2004

TooMuchAbstraction posted:

Do you want a nice display when you print the list? If that's the case, you need to override the __repr__ function. For example:
Python code:
class MyObj(object):
  def __init__(self, a, b):
    self.a = a
    self.b = b
  def __repr__(self):
    return '<MyObj a=%s, b=%s>' % (self.a, self.b)

This is it! I did not know if that was an option or what it was called, thanks guys!

SurgicalOntologist
Jun 17, 2004

Sylink posted:

This is it! I did not know if that was an option or what it was called, thanks guys!

Theyr'e called "magic methods" or dunder methods (for double-underscore) and they define how the class and its instances should integrate with other Python features. There are a to but __repr__ is probably one of the most commonly implemented. You can also define for example what happens if you do arithmetic with your objects, or if you index into them, etc. Probably none of these are relevant to a Car class but for future reference: https://rszalski.github.io/magicmethods/

SnatchRabbit
Feb 23, 2006

by sebmojo
Can someone doublecheck my cronjobs? I'm getting some weird errors and I think I might have a syntax error somewhere in there.

code:
                                "echo \"*/1 * * * * echo \\\"100-\\$(iostat -c 1 2 | sed -n 7p | awk '{print \\$6}')\\\" | bc > /var/log/cpu\" > crontab.txt\n",
                                "echo \"*/3 * * * * stress -c 1 -i 1 -t 90\" > crontab.txt\n",
Basically, I'm trying to write the CPU usage to a file /var/log/cpu but it always comes up 0. I'm thinking the the print is reading the wrong column but I could be wrong.

edit: actually, now I'm thinking the first statement will get overwritten with the single > in the second line, right?

SnatchRabbit fucked around with this message at 19:42 on Apr 18, 2019

lifg
Dec 4, 2000
<this tag left blank>
Muldoon
Yeah, you want >> to append.

SnatchRabbit
Feb 23, 2006

by sebmojo
ok, yeah that was part of it, but I'm still only getting either 0 or 100 as outputs to /var/log/cpu which doesn't seem right.

Now my jobs look like this:
code:
*/1 * * * * echo \"100-\$(iostat -c 1 2 | sed -n 7p | awk '{print \$6}')\" | bc > /var/log/cpu" > crontab.txt
*/3 * * * * stress -c 1 -i 1 -t 90
*/1 * * * * sleep 10 && aws s3api put-object --bucket mybucket --key $(date +\%s).txt --acl public-read --body /var/log/cpu
I'm wondering if the initial echo \"100-\ is just writing into the cpu file without the value from iostat...

CharlestonJew
Jul 7, 2011

Illegal Hen
Hey all, does anyone have any experience using ag-grid in Angular? I'm trying to implement multiple text filters in a grid, but the official documentation I can find (here) is both A: in Javascript, and B: Radio buttons, so I'm completely lost on how to translate that into what I need. I'd just use a floating filter and be done with it, but the higher ups want the text fields to be outside the grid, so I'm lost.

Adbot
ADBOT LOVES YOU

biceps crimes
Apr 12, 2008


CharlestonJew posted:

Hey all, does anyone have any experience using ag-grid in Angular? I'm trying to implement multiple text filters in a grid, but the official documentation I can find (here) is both A: in Javascript, and B: Radio buttons, so I'm completely lost on how to translate that into what I need. I'd just use a floating filter and be done with it, but the higher ups want the text fields to be outside the grid, so I'm lost.

I'm not familiar with ag-grid, but something like this? preview
It's not a complete solution, nor is it using angular, but it should point you in the right direction. The key functions for the ag-grid API external filtering are doesExternalFilterPass, isExternalFilterPresent and making sure you call gridOptions.api.onFilterChanged() when you need to trigger filtering. As long as you meet those API criteria, you can implement the external filtering however you wish.

biceps crimes fucked around with this message at 04:49 on Apr 27, 2019

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