Welcome to Rants and Raves!
I kept hearing that I needed to write, so here is the blog that I ended up starting.
It is mostly an accounting of my progression through creating a web site, nuances with code, and tips about what I did to make things work.
In there you will find sprinkled about some gems of life, and letting loose fun.
Enjoy!
Coding Order Of Operations Between Languages
2023-04-19
Ran into an issue when playing around with Java Script trying to replicate an example page for NFCs.
https://googlechrome.github.io/samples/web-nfc/
I kept getting this error:
uncaught TypeError: Cannot set properties of null (setting 'textContent')
This was in relation to these scripts:
var ChromeSamples = {
...
setStatus: function(status) {
document.querySelector('#status').textContent = status;
},
...
};
if (!("NDEFReader" in window))
ChromeSamples.setStatus("Web NFC is not available. Use Chrome on Android.");
The functions were setup before being called, but that wasn't the issue. The problem was that the HTML was not before the function call. It's hard to set the value of something before that something has even been created. The function definition and HTML to be modified needs to be before the call, but I don't think the order between the HTML and the function definition matters. So you end up with something like this:
var ChromeSamples = {
...
setStatus: function(status) {
document.querySelector('#status').textContent = status;
},
...
};
<div id='output' class='output'>
<div id='content'>Content</div>
<div id='status'>Status</div>
<pre id='log'>Log</pre>
</div>
if (!("NDEFReader" in window))
ChromeSamples.setStatus("Web NFC is not available. Use Chrome on Android.");
The thought was sparked by a comment in this post:
https://stackoverflow.com/questions/54876761/typeerror-cannot-set-property-textcontent-of-null
Note the slight difference between the element id 'id="something"' and the JS selector "'#something'". They aren't quite the same, but that's because a selector without the # selects the element <something>.
https://www.w3schools.com/cssref/css_selectors.php
Sleepy Day
2023-04-18
Had another early morning today, they are a bit jarring. I suppose not having a consistent sleep schedule will also cause problems. But a 4 hour jump either direction is extra rough. Granted, the bigger the jump the tougher the adjustment. At least it's not too often.
Forge Repository Change Issues
2023-04-17
Ran into a snag while getting DataTables visible on the live site. For the public site I had not actually made the switchover from the old Laravel version. As a reminder, changing which repository is being referenced for the site in Forge requires uninstalling the old repository:
Forge -> Server -> Site -> App -> Uninstall Repository
Then you can point the repository to a different one, such as a new Bitbucket project that is for a newer version of Laravel.
Forge -> Server -> Site -> App -> Install Repository -> Bitbucket -> Repository and Branch
One issue that came up was with the migrations, not that they were actually needed. There was one that didn't have a check if it exists, and another that the check for a foreign key completely broke. Because my DB is already setup, thus the need for the checks, I did end up completely commenting out the foreign key section. That I will look into later, but it seems something changed with the DB::raw() method causing it to return a DB query instead of a string, or so the error would indicate.
The other issue ended up being that the environment file for the site was also reset. This included the DB and Google sign in credentials. After those got put back in the site started operating as expected.
NFC Ability?
2023-04-16
I was reminded about the possibility of using Near Field Chip tags for an inventory tag. Most phones nowadays have NFC capabilities, which is how they can be used as digital wallets. It does seem though that it's not quite simple enough for a phone to act as a simple scanner/text entry device using NFCs. I need to do more research, but there is a possibility that I might be able to incorporate some code into he website that can make use of the NFC capability of phones. That way they can as a simple scanner for data entry, or in my case inventory, prior to building a dedicated phone app.
DataTables In Action At The Bottom Of The Blogs
2023-04-15
Now that I've got a little handle of DataTables it's time to start putting it into action. I started by putting one at the bottom of the Blogs page. Due to my initial setup of the blogs I don't have an individual viewing page to link them to just yet, that'll be next. In anticipation for that, and with the admin side of the blogs, I did pull the HTML generation out of the DT script and put it in the controller. You can do this just by referencing an additional variable that you feed into the server response. You end up changing the script like this:
...
columns: [
{ "data": "id",
createdCell: function (cell, cellData, rowData, row, col) {
$(cell).html("<a href='/link/"+cellData+"/moreLink' class='stretched-link'></a>"+cellData);
}
},
...
To:
...
columns: [
{ "data": "id",
createdCell: function (cell, cellData, rowData, row, col) {
$(cell).html(rowData.html);
}
},
...
In the controller you need to create/feed the HTML info you want similar to this:
foreach ($posts as $post) {
...
$nestedData['html'] = "<a href='/link/".$post->id."/moreLink' class='stretched-link'></a>".$post->id;
...
$data[] = $nestedData;
}
$json_data = array(
"draw" => intval($request->input('draw')),
"recordsTotal" => intval($totalData),
"recordsFiltered" => intval($totalFiltered),
"data" => $data
);
echo json_encode($json_data);
Now I can use a conditional based on statement to determine if the link should be to show or perhaps edit the post. I can also use that conditional to determine if I display all the posts or just the ones up to today. I decided to use a comparison against the URL of the page that the DT request came from, the "previous" URL. I decided that the best way was to use 'url()->previous()':
if( url()->previous() == url('/blog/adminURL') ){
$posts = DB::table('blogs');
} else {
$posts = DB::table('blogs')->having('post_at', '<=', Carbon::now());
}
https://stackoverflow.com/questions/17591181/how-to-get-the-current-url-inside-if-statement-blade-in-laravel-4
https://laravel.com/docs/10.x/urls
Note the use of 'having()' in the Eloquent Query Builder. I found that it works better than 'where()' once 'orWhere()' is introduced, which will be present once filtering takes place. It works basically like 'where()' except it behaves more exclusively as an '&&'. where()->orWhere()->having() is like ( 1 || 2 ) && 3.
https://laravel.com/docs/10.x/queries#grouping
Beyond that I just did some rearranging of the Eloquent statements so that I built the query I needed based on some conditions, like admin page and filtering. It allows for less duplicate code and a single location for the actual DB query.
Hacked!
2023-04-14
The wife is posting today. Because she can. Haaiiiiiiiiiiiiiii!!!
Florida Rains
2023-04-13
We drove through a cool rain storm today. It went from nothing to people pulling off the road to nothing in about a half hour of driving. Lots of big drops. Lightning and thunder. It was fun.
Quick Florida Visit
2023-04-12
We made it down to Florida today. It seems the freight out can be a bit hard to come by so it's not necessarily a state you want to bring freight into. We do have something ready to pick up so we can head out, so that's nice. As a person that tends to not like the cold it's been nice to be in the south and have some good warm temperatures. The humidity is one that I'm still getting a bit used to but I do think maybe my body does like it a little bit better than the dry. It's cool to get to see the tropical plants start to mix in with the flora too. On our way we saw some wild pigs eating grass on the side of the highway. Not sure if they were full on boars, but definitely fuzzy pigs. It was cool.
DataTables And Streched-Links
2023-04-11
One of the things that I have done for most of my tables is to make the row of data a hyperlink to the detailed page about that data. For DataTables to match that functionality I need 3 things; a style added to the row, a hyperlink to the detail page added to a column, and a class added to the hyperlink.
Adding a the same style to each row is easy enough, just need to use the 'createdRow' option with the '.css' jQuery method inside the DataTables script array:
createdRow: function( row, data, dataIndex ) {
$(row).css( 'transform', 'rotate(0)' );
},
https://datatables.net/reference/option/createdRow
https://api.jquery.com/css/
https://datatables.net/forums/discussion/57940/sorting-breaks-rowrender#latest
We want to use 'transform: rotate(0)' so that Bootstrap will know how much to stretch the hyperlink.
https://getbootstrap.com/docs/4.3/utilities/stretched-link/#identifying-the-containing-block
For the hyperlink we can use the 'createdCell' option with the '.html' jQuery method inside of one of the column definitions in the DataTables script array:
createdCell: function (cell, cellData, rowData, row, col) {
$(cell).html("<a href='/link/"+cellData+"/moreLink'>"+cellData+"</a>");
}
https://datatables.net/reference/option/columns.createdCell
https://api.jquery.com/html/
https://www.datatables.net/forums/discussion/25111/hyperlink-in-td
Because we create the the entirety of the hyperlink to insert, all we need to do to get the 'stretched-link' class in the hyperlink is to just to include it in the '.html' jQuery method.
$(cell).html("<a href='/link/"+cellData+"/moreLink' class='stretched-link'>"+cellData+"</a>");
Also because we have have the 'stretched-link', and because I don't want to do a lot to remove the hyperlink formatting, I moved the cell content outside of the hyperlink. Now we should end up with something like this:
<script>
$(document).ready(function () {
$('#example').DataTable({
columns: [
{ "data": "dataArrayKey",
createdCell: function (cell, cellData, rowData, row, col) {
$(cell).html("<a href='/link/"+cellData+"/moreLink' class='stretched-link'></a>"+cellData);
}
},
...,
],
createdRow: function( row, data, dataIndex ) {
$(row).css( 'transform', 'rotate(0)' );
},
});
});
</script>
Bootstrap Row-Cols And Order Classes
2023-04-10
Poking on Bootstrap a bit. One of the powerful utilities of Bootstrap is its grid system, even if it might take a bit a fiddling to get things to behave how you think they ought to. The basic layout defines the row, then the columns in the row and any modifications from the defaults:
<div class="row">
<div class="col">Content</div>
...
<div class="col-md-4">Content</div>
</div>
<div class="row">
...
</div>
...
https://getbootstrap.com/docs/5.0/layout/grid/#example
One of the features that will create a quick and dirty grid is the .row-cols-* class:
<div class="row row-cols-lg-3">
<div class="col">Content</div>
...
<div class="col">Content</div>
</div>
This provides a default to all of the columns in the row without having to specify the same details in each column, great if you have a lot of items to make into a grid. You can still make use of the Bootstrap breakpoints to change how many columns you have based on how much screen realestate you have.
https://getbootstrap.com/docs/5.0/layout/grid/#row-columns
Another nice thing is that you can overwrite the .row-cols-* default in any column you need like you would with the basic grid:
<div class="row row-cols-lg-3">
<div class="col col-lg-6">Content</div>
...
<div class="col">Content</div>
</div>
The other big thing that I ran across that can be very handy is the .order-* class, this allows you to change the order the columns are displayed in. Offhand you would just order the content how you would like it displayed, but it does have its uses. For example, if you have 4 columns that on small screens you want them stacked in the order [1 2 3 4], on medium screens you want them in a 2x2 grid in the order [1 3 2 4], and on large screens you want them in a line in the order [2 1 3 4]. Sounds like a mess, but it's not bad with the .row-cols-* and .order-* classes, you end up with something like this:
<div class="row row-cols-md-2 row-cols-lg-4">
<div class="col order-md-1 order-lg-2"></div>
<div class="col order-md-3 order-lg-1"></div>
<div class="col order-md-2 order-lg-3"></div>
<div class="col order-md-4 order-lg-4"></div>
</div>
Once the .order-* class starts being implemented it can have odd results if the other columns it needs to rearrange with don't also have the .order-* class in them. This looks to be because if a column doesn't have a .order-* class it does not get an order applied, so they end up being a "0" order and put in front of the the rest (except for .order-first since it's order is -1). Because of this it would probably be best to just explicitly state each columns order.
https://getbootstrap.com/docs/5.0/layout/columns/#reordering