Tales from iInesat



  • An Article cannot cope with the scope of :wtf: sources to be found there. Heck, a dedicated forum couldn't, so a Topic will have to do.

    Inspired™ by online-train-ticket-web-site-woes

    Corporate Mantra (excepts from):

    1. Thou shall not use Globals
    2. ID's (for HTML Elements) are bad.

    So we were using an obscure JS Framework to render data in the Browser that came from the backend. One of the features was a "grid" for tabulated data. But, like everything else, the original code had been seriously interfered with. In this case a randomly generated, incomprehensible, ID for the Grid e.g x5hl9odxyq4cz I suppose they wanted something to be "unique". Because we "had" to use their (the UI Team's) API's to use the Grid, and because there was no Method to return the randomly generated ID; it was, essentially, inaccessible.

    Ok. Not a problem, no :WTF: here.

    The Module I was working on collected Event Data. These Events could raise Alarms, or be grouped into Incidents. It therefore follows that a Grid would be required for each (or even, god forbid, several grids showing different views of the same data - such was the intended nature of the Product), They could not be combined for reasons that will be explained in another Post.

    Post rendering tinkering / manipulation of data was performed by selections based on the CSS Class Selector by / from buttons (naturally). I quickly discovered that selecting and manipulation data on one grid, would effect all grids. I "discussed" this with the Dev Team Leader (who was my Technical Manager) concerned. Which included a two line method to return the Grid ID. He could not or would not fix the issue. His solution: "There shalt be only One Grid on a page. If you wanted to concurrently view a second then thou shalt create a second page".

    My solution: Dig into the DOM after the Grid had been created, find the random ID and use that to make that Grid an Object with a "known" name. Use that known name as a parent in my dot notation in the rest of the code. Essentially, if the Grid was in focus it would be "this" but "this" was also "that" so there was no confusion when it came to selecting data etc.

    All this was way above Arse Holes' head, he had admitted in the past that he was not a UI Dev - just a Perl one. I have mentioned he was two years out of Uni, but I didn't mention that he was rated an Associate Engineer, which was several rungs below mine of Senior Software Engineer and the first on the ladder.

    My job Title is another story.

    I will add to this (topic) as and when I get inspired.



  • @loose said:

    ID's (for HTML elements) are bad

    Paging @lucas...


  • Discourse touched me in a no-no place

    @loose said:

    Associate Engineer

    Ah, a Lance-Deputy Underminion.



  • @loose said:

    ID's (for HTML Elements) are bad.

    Why? What's the "logic" behind such a statement (if any).



  • @loose said:

    Dig into the DOM after the Grid had been created, find the random ID

    Why? Presumably you already have a DOM object for the grid. Just use the DOM object.



  • It was one of their rules, no explanation was given or considered necessary. To ask for one was borderline heresy.



  • The randomly created ID was just that. A (always) unique "string". It was part of what was supplied when you "asked" for a new Grid. It was actually supplied by Perl and injected into JS Framework's Grid creation API in the form of a data attribute. e.g.

    <div class="nms-kendo-grid" data-nms-grid-id="x5hl9odxyq4cz"....>
    ...grid stuff here....
    </div>
    

    I suspect it was used by the backend so it could "find" it when it streamed data.

    Anyway, as far as the Dom was concerned, it was just another "div". it was never accessed as an "thing" and Class Selectors were used.

    So (with my code) when a grid was "clicked" a delegate function would extract the "data" id by using "first child, third element from the left with a 'r' in it" type stuff and shove it into a variable. Then, any Class Selecting type shite I done would use it as a parent in the Selector.

    I should find a sample of code



  • Actually, I'm kinda with them on this one. There are perf benefits, but if you're writing your website using partial views, or otherwise reusable components, then having an ID means you can never have two such components on the same page.


  • I survived the hour long Uno hand

    I think every possible point on either side was made in this thread:

    https://what.thedailywtf.com/t/is-bootstrap-a-programming-language/2230/54



  • So what, we can't have another nice flamewar here just because we had one already? That's preposterous!



  • Absolutely. Whilst there is nothing stopping you from having the same ID reused on your page, and you can sometimes even still work with them via javascript. This was a "blanket ban" because of some historical reason.

    I have on numerous occasions used ID's (because they can simplify some things), even on "templates" HTML. Because it not beyond the wit of an average programmer to do so. Even on hard coded HTML.

    Eg

    $template = '<div id="' . $productId . '" class="product-class"> . "\n\t" . 'Product Code: ' . $productId....


  • @Yamikuronue said:

    sticking !important

    Second or third most used word in iInesat's CSS for V4.

    Although, to be fair the UI Team Leader did keep on about styling, but he was told that "the styling would be solved at a later date after the UXI Team had done their stuff". Therefore he was also told, UI Devs were to develop without styling :wtf: On one occasion I caught the tail end of this "repeated" discussion, and heard the big boss (Golden Rod) say that they would solve it "... like all the other problems by just keep chucking money at it..." This was early on in the Project. After a couple of months were were actually using Bootstrap just to provide some uniformity across all the modules and, hopefully make the final styling easier to retro-fit.


  • Discourse touched me in a no-no place

    @loose said:

    there is nothing stopping you from having the same ID reused on your page

    But don't do it. IDs really are meant to be unique within the page.

    Library code shouldn't use IDs except for those given to it to use, though it may assume that it has been given IDs to use. Page-specific code may use IDs as it sees fit: it's able to know what is actually there.



  • @dkf said:

    Page-specific code may use IDs as it sees fit: it's able to know what is actually there.

    Personally, I'd really just handle IDs at the absolutely topmost level, and all the partial views/components should obtain a selector for a container and root the selectors in that (preferably via data- attributes, classes are a bit confusing for that).

    You never know when you'll need to refactor so that you'll need two of said partials on the same page, even if it seems silly now.


  • ♿ (Parody)

    @Maciejasjmj said:

    then having an ID means you can never have two such components on the same page.

    Indeed. I use JSF, and it will generate random ids if you don't supply one. However, part of the framework is telling it which components to update after some ajax thing happens, which is done with ids. Fortunately, the actual id is build based on parent components, so it's possible to differentiate. It's also possible to build dynamic ids, so while it's something that trips me up now and then, it's easy enough to fix.

    Not really any more difficult than not having multiple variables named the same thing.



  • @loose said:

    their (the UI Team's) API's to use the Grid

    The UI Team's API is supposed to use the grid?



  • The JS Framework had all the API, documentation, examples etc. The "front end" developers had to use them. But the UI Team were developing the Product UI, so we had to call their Perl API (with all the parameters we needed) and their API would invoke the JS API with "default" values and whatever was left over from "my" parameters.

    I hope that this helps explain


  • Discourse touched me in a no-no place

    @loose said:

    I hope that this helps explain

    On one level, not at all. On another level, it explains everything



  • See rule 2b here.

    I hope that this helps explain



  • @rc4 said:

    See rule 2b here.

    I hope that this helps explain

    Ok, I went. I saw. I :wtf:'d

    Rule 2b. Do not use an apostrophe + s to make a regular noun plural.
    
    Incorrect: Apostrophe's are confusing.    
    Correct: Apostrophes are confusing.    
    Incorrect: We've had many happy Christmas's.    
    Correct: We've had many happy Christmases.
    
    In special cases, such as when forming a plural of a word that is not normally a noun, some writers add an apostrophe for clarity.
    
    Example: Here are some do's and don'ts.
    
    In that sentence, the verb do is used as a plural noun, and the apostrophe was added because the writer felt that dos was confusing. Not all writers agree; some see no problem with dos and don'ts.
    

    I'll be buggered if I can see what I have done wrong / not right now

    Prepares space in :badger: display case in anticipation of another whoosh :badger:


  • FoxDev

    One of the best things about English is its grammatical flexibility.

    One of the worst things about English is its grammatical flexibility.



  • package [redacted]::Module::Discretedata::Controller::Statusview;

    use Mojo::Base '[redacted]::Module::Discretedata::Controller::Gridview';
    use [redacted]::Factory::UI;
    use [redacted]::Factory::Model;
    use [redacted]::DataSource;
    	
    sub index {
    	my $self = shift;
    	my $column_list = undef;	# Ultimately this will point to a Controller or Source to provide User Selection
    
    	if (!defined($self->model())) {
    		$self->model(new [redacted]::Factory::Model()->create('Incidentalarm', 'Discretedata'));
    	}
    	if (!defined($self->data_source())) {
    		$self->data_source(
    			new [redacted]::DataSource(
    				opts  => $self->data_source_option(),
    				model => $self->model()
    			)
    		);
    	}
    	$self->stash(data_source_id => $self->data_source()->id());
    	
    	$self->{ui_factory}  = new [redacted]::Factory::UI();	
    	my $detail_template  = $self->{ui_factory}->create('Jstemplate', contents => 'discretedata/statusview/detail');
    	my $toolbar_template = $self->{ui_factory}->create('Jstemplate', contents => 'discretedata/statusview/toolbar');
    
    	my $status_view_option                = $self->grid_option();
    	$status_view_option->{dataSource}     = $self->data_source();
    	$status_view_option->{columns}        = $self->_default_column_list();
    	$status_view_option->{detailTemplate} = $detail_template;
    	$status_view_option->{toolbar}        = $toolbar_template;
    
    	my $status_view = $self->{ui_factory}->create('grid', opts => $status_view_option);
    	$self->stash(grid => $status_view);
    	$self->stash(grid_id => $status_view->get_dom_id());
    
    	# $status_view->bind_js_callback(
    		# name => 'statusViewDetailTemplateInit',
    		# origin => 'module/discretedata/callback/statusview-detail-callback',
    		# event => 'detailInit',
    	# );
    
    	return $self->render(status_view => $status_view);
    }
    
    sub get_column_list {
    	my $self        = shift;
    	my $column_list = shift;
    
    	if (!defined($column_list)) {
    		$column_list = $self->_default_column_list();
    	}
    
    	return $column_list;
    }
    
    sub _default_column_list {
    	my $self = shift;
    
    	return [
    		'Severity',
    		'StartTime',
    		'Type',
    		'ID',
    		'State',
    		'LatchState',
    		'AckedState',
    	];	
    }
    
    1;
    

    "stash" sends data to the HTML Templater.

    The whole concept of a "default" column list was "my" idea, but was generally considered to be "above my pay grade to worry about".



  • @loose said:

    The whole concept of a "default" column list was "my" idea, but was generally considered to be "above my pay grade to worry about".

    "So about that raise..."



  • I was one of 5 or 6 of the original Senior Software Engineers hired. My position / responsibilty in the Dev Team was just above that of an Intern. Incidentally, I was the last of the original "Senior" engineers to leave / be fired. Internal "promotions" don't count.



  • The HTML "bit"

    % layout 'default';
    % title 'Discrete Data Log View';
    
    <h2 id="<%== $grid_id %>-log-view">Log View</h2>
    
    <% if (ref($log_view) eq 'ARRAY') { %>
    	<% foreach my $item (@{$log_view}) { %>
    		<%== ui $item %>
    	<% } %>
    <% } else {%>
    	<%== ui $log_view %>
    <% } %>
    
    <script>
    	require(['core/grid', 'core/popover', 'module/discretedata/logview'], function () {
    		"use strict";
    
    		var [redacted]GridId = '<%== $grid_id %>',
    			runOnce = false,
    			domString = String.fromCharCode(35) + [redacted]GridId,
    			logviewGrid = jQuery(domString).data('kendoGrid');
    			
    		logviewGrid.bind('dataBound', function(event) {
    			if (runOnce === false) {
    				window.[redacted].discretedata.logview.init([redacted]GridId);
    				//window.[redacted].discretedata.logview._returnDataSource([redacted]GridId, '<%== $data_source_id %>');
    				jQuery(domString + ' div.list-selected-entities-button').[redacted]Popover({"id": [redacted]GridId + "-entity-selection-list-popover", "placement": "bottom", "title": "Selected Events", 'manual': false, "content": jQuery(domString + '-entity-selection-store')});
    			}
    			runOnce = true;
    			jQuery(domString + ' td.k-hierarchy-cell').on('click', function(event) {
    				if (jQuery(event.target).hasClass('k-icon')) {
    					jQuery(this).closest('tr.k-master-row').removeClass('k-state-selected');
    				}
    			});
    			return true;
    		});
    		
    		jQuery(domString).on('click', 'tr.k-master-row', function (event) {
    			if ((!jQuery(event.target).hasClass('k-hierarchy-cell')) && (!jQuery(event.target).hasClass('k-group-cell'))) {
    			window.[redacted].discretedata.logview._flatDataStore('write', [redacted]GridId + '-entity-selection-store', '', 0);
    				jQuery(domString + ' tr.k-master-row').each(function () {
    					if (jQuery(this).hasClass('k-state-selected')) {
    						window.[redacted].discretedata.logview._selectEventClicked([redacted]GridId, jQuery(this));
    					}
    				});
    				return true;
    			} else {
    				jQuery(domString + ' tr.k-master-row').each(function () {
    					jQuery(this).removeClass('k-state-selected');
    				});
    				return false;
    			}
    		});
    	});
    </script>

  • Discourse touched me in a no-no place

    @loose said:

    I'll be buggered if I can see what I have done wrong / not right now

    API is a noun; the plural is APIs. Do not use an apostrophe. (You were OK with the other one; the APIs belong to the UI team).



  • Oh fu chri's sake. Am I to be held responsible for every post I ever made now! Do I have to regression (syntax) check every single one of them, every time?

    :rofl:


  • Discourse touched me in a no-no place

    I was just helping. But I went back for you and re-read the post, and I realized @rc4 wasn't actually telling you what I thought he was. When you say "(the ui team's) api's to use the grid," you're saying "the api that belongs to the UI team is supposed to use the grid" because you're not actually pluralizing the noun, you're making a contraction out of "the api is [supposed] to use the grid".

    HTH, HAND, The More You Know™, etc.



  • I was only pulling you leg (that's three or four or five now)


  • Discourse touched me in a no-no place

    @loose said:

    I was only pulling you leg (that's three or four or five now)

    You keep setting 'em up, I'll keep hitting 'em. I like to help people improve themselves. I'm a helper.



  • @loose said:

    Prepares space in display case in anticipation of another whoosh

    Should I self-flag and get a spellar/gramming badge?


  • Discourse touched me in a no-no place

    I couldn't decided between a gramming flag for you or a whoosh :badger: for @loose so I voted both.

    The gramming flag was arguably more deserved as you seemed to post in this topic just for the sake of pointing it out 😆


Log in to reply