Directive for injecting a string at the cursor position

I was assigned to work on a task where if a user clicks on a specified html element and clicks an add button, then a dropdown’s selected value will appear where the cursor’s last position was.

This was achieved using the Range API https://developer.mozilla.org/en-US/docs/Web/API/Range

I created a directive which is applied on a html element of my choice, a function in the controller that broadcasts the event that the directive is listening to which injects the passed in string value.
I also pass in a CSS ID so as to make sure that we are only injecting inside the clicked on HTML element.

First, here’s the directive:
app.directive('injectPlaceholders', ['$rootScope', function ($rootScope) {
return {
link: function (scope, element, attrs) {
scope.$on('injectSelectedPlaceholder', function (e, placeHolderInfo) {
if (window.getSelection) {
var selection = window.getSelection();

if (selection.getRangeAt && selection.rangeCount) {
var selectionRange = selection.getRangeAt(0);

var userClickedInsideSpecifiedElement = $(selectionRange.commonAncestorContainer).parents(placeHolderInfo.text_area_id).length === 1;

if (userClickedInsideSpecifiedElement ) {
selectionRange.insertNode(document.createTextNode(placeHolderInfo.place_holder));
}
}
}
});
}
}
}]);

Here is the controller function that is bound to the button’s ng-click event that does the broadcasting.
$scope.injectSelectedPlaceholder = function () {
var placeHolderInfo = {
place_holder: $scope.selectedPlaceHolder,
text_area_id: "#UIMessageTextArea"
};

$rootScope.$broadcast('injectSelectedPlaceholder', placeHolderInfo);
};

 

 

Advertisements

Finding a table in a large database where you only know the column names

While working with a large database, I had an entity whose name did not match any of the tables. All I knew were the column names as they are the properties in the data structure in the code.

Fortunately this little bit of SQL shows you all the tables that have a column with the name specified:

use NameOfDatabase
SELECT c.name AS ColName, t.name AS TableName
FROM sys.columns c
    JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE '%NameOfColumn%'

Show text hidden after running an Activator command in Cygwin

This is a weird one which does not have a fix as far as I know.
If you run an Activator command or a command that calls Activator at some point via Cygwin, once it is finished or cancelled, whatever you type in cygwin will not display.
To see what you’re typing, you have to type “stty sane” and hit enter.

Chaining function calls using the result of the previous function

I found myself wanting to apply a set of functions which would return a modified version of the passed in string, to which I wanted to apply the result to the next function. This led to me writing code like so:

val modifiedContent1 = repeatedHeaderRegex.replaceAllIn(content, “”)
val modifiedContent2 = repeatedMultipleWordsWithDateHeaderRegex.replaceAllIn(modifiedContent1, “”)
repeatedSeparatedByBulletPointHeaderRegex.replaceAllIn(modifiedContent2, “”)

Which is pretty ugly and would mean needing to add more code for any additional regexes.

After digging around for some kind of function that would make this less ugly\verbose, I came across the foldLeft function.
This allowed me to pass in the original content string and then apply the current regex item’s findAllIn function to the result of the previous iteration. This does exactly the same as the above code, but looks like so:

Seq(repeatedHeaderRegex, repeatedMultipleWordsWithDateHeaderRegex, repeatedSeparatedByBulletPointHeaderRegex)
.foldLeft(content)((text, regex) => regex.replaceAllIn(text, “”))

This is good to keep in mind in the future as I do need to do something like this fairly often, but I would just do separate functions for each case instead of putting them all in one like I did in the first code block.
I looked for an equivalent in C# and came across the Aggregate function, so I’m glad I can do this there too.

How to get compile time dependency injection working in Play 2.4

I found a couple of articles about this, but none of them worked for me or they missed something important. So I’m going to outline what I did in order to get this to work so that it may help future me or some other developer experiencing the same problem.

 

Create an ApplicationLoader sub class that overrides the load function.

class GrimeyAppLoader extends ApplicationLoader {
  override def load(context: Context): Application = new GrimeyAppComponents(context).application
}

You will then need to implement the components class that the load function will create your application from.

class GrimeyAppComponents(context: Context) extends BuiltInComponentsFromContext(context) with I18nSupport {
  lazy val dbConfig: DatabaseConfig[MySQLDriver] = DatabaseConfig.forConfig("slick.dbs.default")
  lazy val db: JdbcBackend#DatabaseDef = dbConfig.db
  lazy val staticPageService = new StaticPageService(db)

  lazy val staticPageController = new StaticPageController(staticPageService, messagesApi())
  lazy val assetsController = new Assets(httpErrorHandler)

  override def router: Router = new Routes(httpErrorHandler, staticPageController,
    assetsController)

  override def messagesApi(): MessagesApi = new DefaultMessagesApi(environment, configuration, new DefaultLangs(configuration))
}

Finally, you’ll need to reference the application loader class you implemented in your application.conf. Note: This has to be the fully qualified name of the class.

play.application.loader="com.grimey.GrimeyAppLoader"

How to link to an article from within an article in Joomla! 3 without having it assigned to a visible menu

This is likely not the best way to achieve this, but so far I’ve found this to be the simplest way. If I find a better way, I’ll update this article accordingly.

. Create the article that you want an article to link to.
. If one doesn’t already exist, create a hidden menu.
. Create a menu item for the hidden menu.
– Select “Single Article” as the menu item type.
– Select the article you created that the article should link to.
. In the article you want the link to be in, highlight what you want to be the link text. Click the article button at the bottom of the page and select the article you created.

Setting up debugging for a Play project in IntelliJ

I find the IntelliJ documentation doesn’t exactly match what I want, so I’m going to list the steps I took here so I can refer back to them in future, and of course if others have the same issue then they will find this useful too.

. Open command window in relevant directory for the project you want to debug (the one with activator.bat in it).
. In the console, run “activator -jvm-debug” to find out the port to use (usually 9999).
. Then in IntelliJ, navigate to “Run -> Edit configurations -> Add new configuration”.
. Select “Remote”.
. Set “Port” textbox value to the port specified in step 1 (again, most likely 9999).
. Click the spider looking debug button at the top of IntelliJ.
. Back in the console, run the “run” command.

Once you’ve set a break point and navigated to localhost:9000 in your browser, you should be able to step through your code.

Setting values of CKEditor textboxes via Selenium

I needed to test a site’s commenting functionality.
The way that this site would do this is using a lot of javascript while using CKEditor, which does its own javascript stuff in the background.

Because CKEditor does stuff to the textbox html you attach it to, just hooking onto that textbox and setting the value is not going to work.
I found a CKEditor API call that will let you set the value as long as you know the id of the div that CKEditor wraps the generated textbox with. In my case, the name of the div is called “remedy609”. Yours will likely be different.

Selenium allows you to execute your own javascript as if you were doing it on a browser console. So putting these two things together allows you to set a CKEditor text box like so:

val driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_24)
driver.setJavascriptEnabled(true)

val commentText = s”This is an issue generated by a selenium test ${UUID.randomUUID().toString}”

val javascriptExecutor = driver.asInstanceOf[JavascriptExecutor]
javascriptExecutor.executeScript(s”CKEDITOR.instances.remedy609.setData(‘<p>$commentText</p>’)”)

A reason why TryUpdateModel or UpdateModel can pass yet not correctly update the model’s properties.

I just spent over an hour wondering why a post controller function’s call to UpdateModel was not updating the view model’s properties with the values in the form collection.

The mysterious thing was that UpdateModel was not throwing an exception which I as the caller would expect if it does not actually update the properties.

It turns out that the view model had been refactored a tiny bit recently and the relevant properties had their setter made private.
Usually when something wants to modify a property with a private set, a compiler error will appear informing you about this. This was not the case here sadly.

So as a reminder to myself,

When UpdateModel or TryUpdateModel does not update correctly, first thing to do is check that the relevant view model’s properties setters are public.