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
Fish Ladder Theory
Jun 7, 2005

You can do a generic handler like this (assuming jquery):

code:
$(':checkbox').click(function() {
    if ($(this).is(':checked')) {
      // ...etc...
      // you might store the person's name as a value property on the <input> and retrieve it with  .val()
    }    
})
You should probably structure the code so that the selected peoples' names are added to some array, and the input box displays that array with array.join(', '), so you have one source of truth, and names are easy to erase once deselected.


IT BEGINS posted:

I also allow the user to type in a customer name manually, and update the checkboxes if he has typed a valid name.

Not sure what you mean by this part.

Fish Ladder Theory fucked around with this message at 08:27 on Nov 15, 2014

Adbot
ADBOT LOVES YOU

Dominoes
Sep 20, 2007

Hey dudes, running into a display problem with JS and Gmaps.

The text should look like the top popup, not the bottom one. Ie no scrollbar and all displayed. 80% of the time it does, but sometimes it looks like the bottom.


JavaScript code:
var coordsWindow = new google.maps.InfoWindow({
    content:  latFormatted+ '<br/>' + lonFormatted + '<br/>' +
        String(elevation) + "'",
    position: event.latLng,
    title: "placeholder"
})
coordsWindow.open(map)

Dominoes fucked around with this message at 11:46 on Nov 15, 2014

karms
Jan 22, 2006

by Nyc_Tattoo
Yam Slacker
Maybe set maxWindow to be slightly bigger than what maps thinks it needs to be?

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Dominoes posted:

Hey dudes, running into a display problem with JS and Gmaps.

I think that is a known problem, try the workaround in this: http://stackoverflow.com/questions/19954893/google-map-infowindow-displays-scroll-bars-in-google-chrome

IT BEGINS
Jan 15, 2009

I don't know how to make analogies

Fish Ladder Theory posted:

Not sure what you mean by this part.

Basically if I have three checkboxes with values 'A', 'B', and 'C', then when the user types 'A, B' into the input box, I'd like to check the corresponding checkboxes. I guess I can't get away from declaring a bunch of click handlers, though.

Fish Ladder Theory
Jun 7, 2005

you only need one click handler-- a generic one on any :checkbox

It's a fun exercise so I went ahead and made a mockup here, including auto checking when you type in a name:
http://jsfiddle.net/vyvf3a2e/4/

Only thing I didn't do is automatically uncheck a box when the user deletes a name manually

spatula
Nov 6, 2004

IT BEGINS posted:

This is maybe a more vague best-practices related question, but I'm having some trouble organizing my code for a particular feature. I have an input text box that a user can fill in that's also controlled by a list on checkboxes/customer names. The functionality I have is that when the user clicks on a checkbox/customer name, that value is added to the input box - multiple customers can be selected, with commas as a delimiter. I also allow the user to type in a customer name manually, and update the checkboxes if he has typed a valid name.

My issue is that right now, I'm basically making a form with a bunch of click handlers going back and forth. It's not particularly reusable, and I am going to be adding several more controls like this to the page, so I'd like this JS not to turn into like 50 "$(elt).on('click', ...)" lines. Any tips?

Why would you need all those lines that do exactly the same thing? Assuming you can identify all the checkboxes with a single class, you just need $('.checkboxclass').on('click', function append checkbox label to whatever) to have it work for every one of them.

IT BEGINS
Jan 15, 2009

I don't know how to make analogies

spatula posted:

Why would you need all those lines that do exactly the same thing? Assuming you can identify all the checkboxes with a single class, you just need $('.checkboxclass').on('click', function append checkbox label to whatever) to have it work for every one of them.

Good point. The reason I thought I would have to have multiple handlers is because I have 4-5 controls that all function this similar way but work with different models. However, I can definitely still just create one handler that binds all of them and uses some other attribute to determine which model to hook up to. Thanks for the all the help guys! :)

RobertKerans
Aug 25, 2006

There is a heppy lend
Fur, fur aw-a-a-ay.
Edit, far too slow, anyway

IT BEGINS posted:

This is maybe a more vague best-practices related question, but I'm having some trouble organizing my code for a particular feature. I have an input text box that a user can fill in that's also controlled by a list on checkboxes/customer names. The functionality I have is that when the user clicks on a checkbox/customer name, that value is added to the input box - multiple customers can be selected, with commas as a delimiter. I also allow the user to type in a customer name manually, and update the checkboxes if he has typed a valid name.

My issue is that right now, I'm basically making a form with a bunch of click handlers going back and forth. It's not particularly reusable, and I am going to be adding several more controls like this to the page, so I'd like this JS not to turn into like 50 "$(elt).on('click', ...)" lines. Any tips?

You have 2 [groups of] inputs, if that (you could just have one on the checkboxes but), so only really need 2 handlers, which should make it easier to reason the interconnected logic bit afterwards. You can ascertain what the user has input from each of those handlers - look at http://learn.jquery.com/events/event-delegation

Pull all the names out into an array to check against.

Then maybe write two overall handler functions. 1. is the check box checked? if not, take the name and add it to the text box, and apply checked. 2. has the user entered text (keyup and very open to issues unless you have some kind of 'add' button) & what's the latest thing written? split on commas, take the last array item, and check if it's in the names array - if so, check the relevant check box.

You can further split this down into smaller, reusable functions, and just pass those as values.

There are other ways to do it, but hopefully that gives you an idea

RobertKerans fucked around with this message at 16:06 on Nov 17, 2014

Dominoes
Sep 20, 2007

Thanks dude.

Raskolnikov2089
Nov 3, 2006

Schizzy to the matic
I really hate coming up with meaningful variable names :(

Dominoes
Sep 20, 2007

Raskolnikov2089 posted:

I really hate coming up with meaningful variable names :(
It's ok.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Raskolnikov2089 posted:

I really hate coming up with meaningful variable names :(

2 hardest problems in computer science: naming things, and cache invalidation.

Suspicious Dish
Sep 24, 2011

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

Subjunctive posted:

2 hardest problems in computer science: naming things, cache invalidation, and off-by-one errors

Pollyanna
Mar 5, 2005

Milk's on them.


Alright, that was pretty good.

darthbob88
Oct 13, 2011

YOSPOS
Is there a good way for a JS file to read its own URL/query string? As in, if I load a file from "dick.butt/javascript.js?id=foo", can javascript.js somehow detect ID? The best way I've found so far is something like this, where a script finds the element that loads it and parses its own src attribute. If there's a better solution to the problem on that page, I'd like to hear about it, otherwise here's a solution for anybody else with the same problem.

DimpledChad
May 14, 2002
Rigging elections since '87.
You could use RequireJS/another AMD loader to load the script, and then initialize the module with some parameters.

Edit: see this SO question: http://stackoverflow.com/questions/10319027/requirejs-pass-parameters-into-module-for-initialization

From the answer there, do this:

code:
define(['dep1', 'dep2', 'dep3'], function (dep1, dep2, dep3) {
    var module = {
        ...
    };

    var init = function (id) {
        // Initialize here
        return module;

    };

    return init;
});
and then from the script that loads it, do
code:
var foo = require('foo');

foo.init(id);
Edit: another approach, if you're working on the backend, too, would be to use a URL rewrite in Apache or whatever to serve the JS up via a script that injects the parameters.

DimpledChad fucked around with this message at 00:55 on Nov 21, 2014

darthbob88
Oct 13, 2011

YOSPOS
I suppose the best way would be to use additional infrastructure. I'll go with the find script element/parse query string method. The real problem I have right now is minimizing the amount of work necessary to load my file, so replacing that initial var id = "foo" with require.js really doesn't save me anything. Good solution, but not for me.

Storgar
Oct 31, 2011
Kind of a n00b question. What is the best practice for waiting for the DOM to load before running your scripts?

1. Is it common to just wrap all of your scripts in window.onload? Do people spend the trouble of only doing this if necessary?

2. I'm making some ajax calls that take some pre-existing divs and modify the innerHTML as well as some other functions that might modify the DOM, and event listeners. I'm not getting any errors, but it's a simple project so far. Do I need to wrap this in window.onload?

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Storgar posted:

Kind of a n00b question. What is the best practice for waiting for the DOM to load before running your scripts?

1. Is it common to just wrap all of your scripts in window.onload? Do people spend the trouble of only doing this if necessary?

2. I'm making some ajax calls that take some pre-existing divs and modify the innerHTML as well as some other functions that might modify the DOM, and event listeners. I'm not getting any errors, but it's a simple project so far. Do I need to wrap this in window.onload?

Are you using jQuery? Use $(function(){}).

If not, use window.addEventListener('DOMContentLoaded', function () {}).

You should probably use jQuery or some other library anyway.

Storgar
Oct 31, 2011
Uhhhhhhh no. I'm messing around with a personal project to learn Javascript and I'd figure I should learn what's "vanilla" javascript. If you have reasons for me to use jQuery, please tell. :allears:

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.
Because if you're doing it in a web page, you're learning "JavaScript for the web", which means you might as well simplify the web-centric stuff like window.onload by using jQuery to initialise your scripts.
If you're not doing "JavaScript for the web" then why do you even care about how your scripts get executed? Use jQuery.

Second to that, if you're just trying to learn JavaScript you could as easily go mess about in NodeJS and you won't have to battle with browser specifics.

Learning JavaScript isn't really about learning it as a language these days, it tends to also come with a lot of necessary framework knowledge (like one of jQuery, knockout, or various node libs) because by itself it's not good for much, besides making you angry at the world. Anyone who did webdev before 2006 can attest to this.

Storgar posted:

1. Is it common to just wrap all of your scripts in window.onload? Do people spend the trouble of only doing this if necessary?

You don't need to wrap absolutely everything, it's not like a class definition or anything. This is just the entry point for the script execution.
This is usually done because if you want to do anything with the DOM, you need the DOM to be fully loaded. If you just write code in the <script> tag, then it'll execute as soon as that tag is loaded, and half your document might not be ready.

Example:
code:
$('#myDiv').remove();

<div id="myDiv">derp</div>
The above code won't work. The <script> chunk will execute before the <div> is loaded. You can correct this by only executing the javascript when the DOM is ready

code:
$(document).ready(function() {		// Note: there's a shortcut for this: $(function() { });
	$('#myDiv').remove();
});

<div id="myDiv">derp</div>

Storgar posted:

2. I'm making some ajax calls that take some pre-existing divs and modify the innerHTML as well as some other functions that might modify the DOM, and event listeners. I'm not getting any errors, but it's a simple project so far. Do I need to wrap this in window.onload?

You don't need to wrap the whole thing. Generally people will write a class-type thing and then execute an initaliser once the DOM is ready.
By the way, there's a bazillion ways to do this, don't take this as the be-all recommended approach, but here's an example:
code:
// Pretend this is in an external file like myStaticThing.js
var myStaticThing = {

	// Initialise the class
	init: function() {
		var self = this;
		
		// Hook: Click button
		$('#myButton').on('click', function(event) {
			var $button = $(this);
			self.makeNoise($button.attr('value'));
		});
	},

	// Callback: Make button alert a value
	makeNoise: function(value) {
		alert(value);
	}
};


<!-- And this is in the .html file -->
<button id="myButton" value="abc123">I'm A Button</button>

// ..And this is in script tags
$(function() {
	myStaticThing.init();
});
Sorry there's no script tags to make this more readable, forum thinks it's a XSS attack.

Storgar
Oct 31, 2011
Wow, great response! I guess its not too early to start using jQuery. Is there anything that stands out in particular that jQuery makes a lot easier? (besides cross browser compatibility)

Storgar fucked around with this message at 04:44 on Nov 24, 2014

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

Storgar posted:

Wow, great response! I guess its not too early to start using jQuery. Is there anything that stands out in particular that jQuery makes a lot easier? (besides cross browser compatibility)

If you're not worrying about older browsers you can skip jquery just fine. It does add some convenience (for example, adding event listeners to a bunch of elements matching a similar selector), but its definitely not necessary.

spatula
Nov 6, 2004
Here's a cool website that shows a lot of common Jquery stuff next to how it's done in pure JS. Good reading.

http://youmightnotneedjquery.com/

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.
Be aware that jquery's default mode of operation is to fail silently. If you get an element using $(".thing") and then bind an event to it, things work, however if it finds nothing, you get no clear and immediate error. Jquery is super permissive and meant to pave over mistakes and just finish its runtime without too many errors.

Sometimes that's what you want, but for me I often prefer the native DOM API because it blows up with a clear error when my assumptions are off.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Storgar posted:

Wow, great response! I guess its not too early to start using jQuery. Is there anything that stands out in particular that jQuery makes a lot easier? (besides cross browser compatibility)

jQuery is less verbose than vanilla javascript.

One other library that I like a lot is underscore (or lodash), but they fill a different purpose.

Munkeymon
Aug 14, 2003

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



spatula posted:

Here's a cool website that shows a lot of common Jquery stuff next to how it's done in pure JS. Good reading.

http://youmightnotneedjquery.com/

The little slider only goes back to IE 8 :allears:

Yeah, that's plenty good for a lot of people, but still.

qntm
Jun 17, 2009
I suppose it's implicit that if you need to support IE7 you probably do need jQuery.

Pollyanna
Mar 5, 2005

Milk's on them.


Require.js is bizarre and I just cannot wrap my head around it. I have a Yeoman-generated app that's based on a React UI, and I just cannot figure out how I'm supposed to add Backbone to the dependencies and be able to use it. I ran bower install backbone --save then grunt bower just like the Yo docs tell me to do, and it says that it "Updated RequireJS config with installed Bower components" , but Backbone is never actually loaded and the config doesn't actually change! :( Require.js has been such a pain in the rear end to wrangle that I'm really regretting using it for my project. Can anyone tell me how to get this frickin' thing to work?

If it helps, here's my main.jsx:

code:
/** @jsx React.DOM */
'use strict';

require.config({
	baseUrl: 'scripts',
	paths: {
		react: 'script/react.min'
	},
	shim: {
		react: {
			exports: 'React'
		}
	}
});

require(['app'], function (App) {

	// use app here
	React.renderComponent(
		<App />,
		document.getElementById('app')
	);
});

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

Pollyanna posted:

Require.js is bizarre and I just cannot wrap my head around it. I have a Yeoman-generated app that's based on a React UI, and I just cannot figure out how I'm supposed to add Backbone to the dependencies and be able to use it. I ran bower install backbone --save then grunt bower just like the Yo docs tell me to do, and it says that it "Updated RequireJS config with installed Bower components" , but Backbone is never actually loaded and the config doesn't actually change! :( Require.js has been such a pain in the rear end to wrangle that I'm really regretting using it for my project. Can anyone tell me how to get this frickin' thing to work?

If it helps, here's my main.jsx:

code:
/** @jsx React.DOM */
'use strict';

require.config({
	baseUrl: 'scripts',
	paths: {
		react: 'script/react.min'
	},
	shim: {
		react: {
			exports: 'React'
		}
	}
});

require(['app'], function (App) {

	// use app here
	React.renderComponent(
		<App />,
		document.getElementById('app')
	);
});

You need to add backbone: "path/to/backbone" to the paths key in the config.

Also, require.js doesn't load anything until you reference it. Does app reference backbone in the dependency list? If not, it will not get loaded in your example.

Pollyanna
Mar 5, 2005

Milk's on them.


Like this?

code:
/** @jsx React.DOM */
'use strict';

require.config({
	baseUrl: 'scripts',
	paths: {
		react: 'script/react.min',
		backbone: 'script/backbone'
	},
	shim: {
		react: {
			exports: 'React'
		},
		backbone: {
			exports: 'Backbone'
		}
	}
});

require(['app', 'backbone'], function (App, Backbone) {

	console.log(Backbone);

	// use app here
	React.renderComponent(
		App(null ),
		document.getElementById('app')
	);
});
Cause even if I do this, it fails, and I've noticed that Backbone isn't even loaded in bower_components under Sources. :(

down with slavery
Dec 23, 2013
STOP QUOTING MY POSTS SO PEOPLE THAT AREN'T IDIOTS DON'T HAVE TO READ MY FUCKING TERRIBLE OPINIONS THANKS
something tells me "backbone" isnt the filename you're trying to load. maybe a .js?

Xenoveritas
May 9, 2010
Dinosaur Gum
Require.js doesn't want you to add the '.js', it adds them for you.

Unfortunately I don't know enough about Bower or this specific usecase to provide useful information, I've only ever used require.js with web applications.

Met48
Mar 15, 2009
Can't help with the grunt bower issue, but assuming combo-breaker-app is your app (or app layout) then Bower installs to app/bower_components (set by .bowerrc). Your paths need to reach this directory, relative to baseUrl, which is relative to the server root (/app).

There's some other changes I'd suggest:
  • Backbone depends on underscore; verify that it is installed (bower install underscore --save) and add it to the paths config
  • The react path also needs to reference the bower component
  • Backbone and React do not require a shim, at least with the most recent versions
  • Optional, but you may wish to update React; bower.json specifies a version that's a year old
  • React doesn't appear to be loaded by any script, it's being included directly in index.html. You can remove that reference if the files which need React each require it. This does mean updating most of your view files though.
  • The version of React in your config is without addons, but the version in index.html is with addons.

So the full app/jsx/main.js would look something like this:

code:
/** @jsx React.DOM */
'use strict';

require.config({
    baseUrl: 'scripts',
    paths: {
        react: '../bower_components/react/react-with-addons.min',
        backbone: '../bower_components/backbone/backbone',
        underscore: '../bower_components/underscore/underscore'
    }
});

require(['react', 'backbone', 'app'], function (React, Backbone, App) {
    console.log(Backbone);

    // use app here
    React.renderComponent(
        <App />,
        document.getElementById('app')
    );
});
You can also use absolute paths:

/bower_components/backbone/backbone.js

The .js extension is necessary for absolute paths.

Met48 fucked around with this message at 22:56 on Nov 24, 2014

Kobayashi
Aug 13, 2004

by Nyc_Tattoo

Xenoveritas posted:

Require.js doesn't want you to add the '.js', it adds them for you.


Modern web tooling is such a loving joke.

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

Kobayashi posted:

Modern web tooling is such a loving joke.

It gets me every time. I will never understand why they thought it was a good idea.

Xenoveritas
May 9, 2010
Dinosaur Gum
Because conceptually you're not including files, you're including named modules. Think of it like import in Python or use in Perl or whatever in some other scripting language that has modules.

Of course I have no clue why that logic also applies to the part where you're explicitly indicating where to locate a given named module.

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

Xenoveritas posted:

Of course I have no clue why that logic also applies to the part where you're explicitly indicating where to locate a given named module.

That's kind of my point. Pick one and stick with it.

Adbot
ADBOT LOVES YOU

Pollyanna
Mar 5, 2005

Milk's on them.


Xenoveritas posted:

Because conceptually you're not including files, you're including named modules. Think of it like import in Python or use in Perl or whatever in some other scripting language that has modules.

Of course I have no clue why that logic also applies to the part where you're explicitly indicating where to locate a given named module.

gently caress that, I've used Python for a longass time and importing is much more clear and obvious than this. This is more like trying to write virtualenv from scratch in your own little file.

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