TexasSwede
texasswede@gmail.com
  • About this blog
  • My Website
  • My Resume
  • XML Export Tool
  • Photos

Category Archives: jQuery

Calling a Notes web agent from another server using JSONP

Posted on November 6, 2015 by Karl-Henry Martinsson Posted in Javascript, jQuery, Lotusscript, Notes/Domino, Programming, Web Development Leave a comment

In my MWLUG presentation (as well as in a couple of entries on this blog) I talk about how you can access Domino data from a regular webpage using jQuery and a Lotusscript agent returning data as JSON. The issue with this solution is that the web page must be on the same web application path as the Domino agent. You can’t do what’s known as cross-domain Ajax.

For example if the Domino server is domino.texasswede.com but you have the webpage hosted at www.texasswede.com, it will not work. The security in Javascript does not allow calls across servers like that. There is however an easy solution, and it is called JSONP. What you do is to return not JSON but a call-back function with the JSON data as the argument.

So instead of returning this:

{ "firstName":"Karl-Henry", "lastname":"Martinsson","email":"texasswede@gmail.com" }

you would have the Lotuscript agent return this:

personCallBack({ "firstName":"Karl-Henry", "lastname":"Martinsson","email":"texasswede@gmail.com" })

Let’s assume we call the agent GetPersonData.jsonp.  On the calling side (in the jQuery code) you would then use this code:

$.ajax({
    url : "http://domino.texasswede.com/database.nsf/GetPersonData.jsonp?OpenAgent",
    dataType:"jsonp"
});

Finally you write the Javascript call-back function that will accept the data:

function personCallBack(data) {
    $("#firstName").html(data["firstName"]);
    $("#lastName").html(data["lastName"]);
    $("#emailAddress").html(data["email"]);
}

You can of course make this as advanced as you like but this is the basics. I have updated the JSON class I use for stuff like this to include a method to return JSONP. The new function is called SendJSONPToBrowser() and takes a string with the name of the call-back function as argument, for example like this:

Call json.SendJSONPToBrowser("personCallBack")

Below is the updated class (if you downloaded my sample database from MWLUG you have the older version of it). Enjoy!

 

%REM
	Library Class.JSON by Karl-Henry Martinsson
	Created Oct 9, 2014 - Initial version
	Updated Nov 6, 2015 - Added JSONP support
	Description: Class to generate simple JSON from values
%END REM

Option Public
Option Declare

Class JSONdata
	Private p_json List As String
	
	Public Sub New()
		'*** Set default value(s)
		me.p_json("ajaxstatus") = ""
	End Sub
	
	%REM
		Property Set success
		Description: Set success to true or false
	%END REM
	Public Property Set success As Boolean
		If me.success Then 
			Call me.SetValue("ajaxstatus","success")
		Else
			Call me.SetValue("ajaxstatus","error")
		End If
	End Property
	
	%REM
		Property Get success
		Description: Not really used...
	%END REM
	Public Property Get success As Boolean
		If me.p_json("ajaxstatus") = |"success"| Then
			me.success = True
		Else
			me.success = False
		End If
	End Property
	
	%REM
		Sub SetMsg
		Description: Set msg item
	%END REM
	Public Sub SetMsg(message As String)
		Call me.SetValue("msg",message)
	End Sub
	
	Public Sub SetErrorMsg(message As String)
		Call me.SetValue("errormsg",message)
		me.success = False
	End Sub
	
	Public Sub SetValue(itemname As String, value As String)
		Dim tmp As String
		Dim delimiter As String
		'*** Check for quote (double and single) and fix value if needed
		tmp = Replace(value,Chr$(13),"<br>")
		tmp = FullTrim(Replace(tmp,Chr$(10),""))
		If InStr(tmp,|"|)>0 Then
			If InStr(tmp,|'|)>0 Then
				tmp = Replace(tmp,|"|,|"|)
				delimiter = |"|
			Else
				delimiter = |'|
			End If
		Else
			delimiter = |"|
		End If
		'*** Store value with delimiter in list
		me.p_json(itemname) = delimiter & tmp & delimiter
	End Sub
	
	Public Sub SetData(itemname As String, value As String)
		'*** Store value in list
		me.p_json(itemname) = value
	End Sub
	
	%REM
		Function GetJSON
		Description: Return a JSON object as text
	%END REM
	Function GetJSON As String
		Dim json As String
		'*** Opening curly braces + CR
		json = "{" + Chr$(13)
		'*** Loop through all list elements and build JSON
		ForAll j In me.p_json
			json = json + |"| + ListTag(j) + |":| + j + "," + Chr$(13)
		End ForAll
		'*** Remove the comma after the last item
		json = Left$(json,Len(json)-2) + Chr$(13)
		'*** Add closing curly bracket and return JSON
		json = json + "}"
		GetJSON = json 
	End Function
	
	%REM
		Sub SendToBrowser
		Description: Print JSON to browser, with correct MIME type
	%END REM
	Public Sub SendToBrowser()
		'*** MIME Header to tell browser what kind of data we will return (JSON).
		'*** See http://www.ietf.org/rfc/rfc4627.txt
		Print "content-type: application/json"
		Print me.GetJSON
	End Sub
	
	%REM
		Sub SendJSONPToBrowser
		Description: Print JSON to browser, with correct MIME type
	%END REM
	Public Sub SendJSONPToBrowser(callbackFunction As String)
		'*** MIME Header to tell browser what kind of data we will return (Javascript).
		'*** See http://www.rfc-editor.org/rfc/rfc4329.txt
		Print "content-type: application/javascript"
		Print callbackFunction + "(" + me.GetJSON + ")"
	End Sub
	
End Class

 

My MWLUG presentation

Posted on August 20, 2015 by Karl-Henry Martinsson Posted in Bootstrap, HTML/CSS, IBM/Lotus, Javascript, jQuery, Lotusscript, MWLUG, Notes/Domino, Web Development Leave a comment

You can find my presentation from yesterday here.

I plan to publish the speaker notes soon, after I clean them up some.

Microsoft releases Visual Studio 2015

Posted on July 20, 2015 by Karl-Henry Martinsson Posted in .NET, Bootstrap, C#, jQuery, Microsoft, Programming, Visual Studio, Web Development Leave a comment

Microsoft today released the latest version of their development environment Visual Studio. There are even free versions, including the complete IDE Visual Studio Community and the code editor Visual Studio Code (available for Widnows, Linux and OSX).

Visual Studio now includes even more tools for cross platform mobile development for iOS  and Android. There is even an Android emulator included. The web development part supports tools and frameworks like Angular, Bootstrap, jQuery, Backbone and Django.

And naturally the IDE also supports Windows, including Windows 10 (expected to be released at the end of the month).

I have been using tools in the Visual Studio family for many years, I started with a beta of Visual Basic 1.0 a long time ago, and used all version up to and including VB 6.0. I also played around some with Visual C++ and even Visual J++. After that I focused mainly on Lotus Notes development, but recently I have started some C#/.NET projects at work using Visual Studio Community 2013.

MWLUG in Atlanta – I will be presenting!

Posted on July 4, 2015 by Karl-Henry Martinsson Posted in Bootstrap, Community, IBM/Lotus, jQuery, Lotusscript, MWLUG, Web Development 1 Comment

It is less than 7 weeks left until MWLUG, the Midwest Lotus User Group conference. This year the conference takes place in Atlanta, between August 19 and 21. During the three days there will be over 40 technical session and workshops on collaboration, receptions and networking opportunities, as well as access to experts of IBM solutions, both from IBM and other companies. The topics includes application development, system administration, best practices, customer buisness cases and innovation/future plans by IBM. Breakfast and lunch is included for two days as well. And all this for the cost of only $50 per person! The event takes place at Ritz-Carlton in downtown Atlanta. There is a block of rooms reserved at a special conference rate of $149.00 per night.

One of the sessions will also mark my personal debute as a speaker at a conference. I will present “Break out of the box – Integrate existing Domino data with modern websites” where I will talk about how to integrate websites built either within Domino or on other platforms with backend data that resides in a Domino database. I will talk about how you can build a modern looking website using tools like jQuery and Bootstrap and seamlessly integrate them with existing data on your trusty Domino server using JSON and Ajax. I will also provide plenty of example code ready for you to bring home and start playing with.

A number of IBM Champions will be presenting, as well as IBMers and other industry experts. So no matter your interest, I am sure you will find plenty of good sessions. I am sure I will have a hard time picking which sessions to attend!

So what are you waiting for? Go to http://www.mwlug.com and register! See you there!

 

Microsoft and jQuery Ajax calls – not using standards

Posted on March 10, 2015 by Karl-Henry Martinsson Posted in .NET, jQuery, Microsoft, Web Development 3 Comments

I recently started using C# and .NET for the first time to build a web application. It is just a proof of concept application where I am trying to implement CRUD (Create, Read, Update and Delete) though jQuery and Ajax calls from a simple webpage. The application should let me retrieve a list of all companies in the database, get information about a specific company (based on a company id), update an existing company (and create a new company in the database if it does not exist) and finally allow a company to be deleted.

I been doing these things for years using IBM Domino as the backend, simple reading the query string and parsing the name-value pairs before performing actions based on the values. So when I started using Visual Studio I naturally thought things would work the same there.

But I found out that ASP.NET is using a different method to address web resources. It uses the concept of routes, so instead of adding information passed to the server using the query string, the data is passed in the actual URL:
To get a list of all companies you would call /api/Company, and to get information about a specific company you add the company id (/api/Company/Q1234). If I want to pass two arguments to the server, for example to get all companies in a specific city and state, you would call /api/Company/TX/Dallas.

In my opinion, this gives you much less flexibility than if  you pass arguments in the query string. You must put the arguments in the correct order, and it is much harder to use optional arguments. One example of where I used optional argumenst is for sort order. In some cases I want the companies to be returned in descending order, instead of the default ascending. Or I want to sort on a specific column/values. In those cases I pass along a special argument, but normally I don’t. Less data to transfer that way, and cleaner code. But it still works.

It is when you want to perform a POST of form data to the server that it get really complicated and annoying. This is the sample code using the ASP.NET Web API generated by Visual Studio 2013:

// POST: api/Company
public void Post([FromBody]string value)
{
    ... do stuff here
}

As you perhaps can tell, this function only take one argument, which is pretty useless in a real application. And you can’t just add additional arguments in the declaration. One way to do it (as described here) is to use a data transfer object containing all the arguments, which then is used in the function:

public class CompanyDTO
{
    public string CompanyID { get; set; }
    public string LegalName { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZIP { get; set; }
}

// POST: api/Company
public string Post(CompanyDTO Company)
{
    return Company.LegalName + " in " + Company.City + ", " + Company.State;
}

The issue here is that you need to put the arguments in exactly the same order in the Ajax call (and hence the query string) as they are declared in the code. You also can’t (as far as I understand) send only updated values, you need to always send all the fields, even if just one field has been changed.

So what should one do? The best solution I found this far is to pass the data from the browser as a string, containing JSON. Not as a JSON object, as that will not work.

So do not do this:

$.ajax({
    type: "POST",
    url:  "api/Company/",
    data: {'city':'Dallas','legalname':'Test Company, LLC'},
    contentType: "application/json; charset=utf-8",
    dataType: "json"
});

The browser will just convert the JSON object to name-value pairs, and you end up with null in your code. Instead, change the jQuery code to this:

$.ajax({
    type: "POST",
    url:  "api/Company/",
    data: "{'city':'Dallas','legalname':'Test Company, LLC','Owner':'Karl-Henry Martinsson'}",
    contentType: "application/json; charset=utf-8",
    dataType: "json"
});

Now it will work! Notice the small change, I added quotes around the JSON. An added bonus is that you don’t need to pass along all fields, just the ones you want/need in any order. And if you pass along a field/name that is not defined on the server, it will simply be ignored.

You probably don’t want to build the data string manually. Perhaps you want to loop though certain fields and retrieve the values to pass to the server. You would do something like this:

// Create a new empty object
var Company = { };
// Loop through all elements with the class 'dataField' and
// build an object with the ID of the element as the name.
$('.dataField').each(function() {
  Company[this.id] = this.value;
});

$.ajax({
  type: "POST",
  contentType: "application/json; charset=utf-8",
  url: "/api/Company",
  data: JSON.stringify(Company),
  dataType: "json"
});

I use JSON.stringify to convert the JSON object to a string before sending it to the server.

So this is what I found out. Hopefully it will help someone. I am still a bit frustrated that Micorosft once again decided to do things a different way than the rest of the world, but I guess one should not be surprised at that.

 

 

 

 

File Upload in Classic Domino Web using jQuery and Bootstrap

Posted on January 8, 2015 by Karl-Henry Martinsson Posted in Bootstrap, IBM/Lotus, jQuery, Notes/Domino 6 Comments

This week I was asked to create a simple web form where customers could fill out a few fields, attach two files and submit it for review. The document with the information and attachments are saved into a Domino database, so it can be processed thought the Notes client by the internal staff.

These days I mainly use Bootstrap (and jQuery) to design the webpages, since Bootstrap makes it very quick and easy to get a nice clean look of the page. Using jQuery allows me to do some nice manipulations of the DOM, hiding and showing sections as needed for example, or disable the submit button until all required fields have been filled out.

It has been a long time since I worked with the file upload control in Domino, and it was as ugly as I remembered it. But I knew I had seen some nice jQuery/Bootstrap file upload controls, so I located one that I liked in the Jasny plugin library. If you haven’t already, take a look at those components!

So how do I tie this control to the Domino file upload control? As so many times before, Jake Howlett and his excellent site CodeStore comes to the rescue. He wrote an article back in 2005 about how to fake a file upload control, and that code can be used as-is, and combined with the Jasny plugin.

Here is what my code looks like after doing that:

<div class="col-md-6">
  <label>Producer Agreement</label>
  <!-- File Upload -->
  <div class="fileinput fileinput-new input-group" data-provides="fileinput" title="Attach file here">
    <div class="form-control" data-trigger="fileinput">
      <i class="glyphicon glyphicon-file fileinput-exists"></i>&nbsp;
      <span class="fileinput-filename"></span>
    </div>
    <span class="input-group-addon btn btn-default btn-file">
      <span class="fileinput-new">Select file</span>
      <span class="fileinput-exists">Change</span>
      <input type="file" name="%%File.1" class="required">
    </span>
    <a href="#" class="input-group-addon btn btn-default fileinput-exists" data-dismiss="fileinput">Remove</a>
  </div>
</div>

On the second file upload control I just change the name to “%%File.2”. The form tag must have the encoding set to multipart/form-data, so this is what it looks like for me:

<form name="SubmissionForm" id="SubmissionForm" 
action="AgencySubmission?CreateDocument" method="post" 
enctype="multipart/form-data">

It all worked perfectly. I was able to attach the files and submit the form, and the files showed up in the Notes client. What I did not like was the dreaded “Form processed” message. I tried a few different things, using the $$Return field, etc. But nothing worked.

To make a long story short(er), and without diving too deep into details, I had the form setup to render as HTML, not as a Notes form, thus using ?ReadForm to display it. But when I changed it to Notes on the form properties, the Domino server added it’s own Javascript code to submit the form (in addition to extra HTML). I found out a way to trick Domino to “hide” that Javascript code, so only my jQuery/Javascript code was sent to the browser.

Then I wrote my own code to do a HTTP POST submission of the form as multipart/form-data:

$('form#SubmissionForm').submit(function(event){
  // Disable the default form submission
  event.preventDefault();
  // Gat all form data  
  var formData = new FormData($(this)[0]);
  $('input').each( function() {
    formData.append($(this).attr('id'),$(this).val());
  });
  // Submit form to Domino server using specified form
  $.ajax({
    url: 'AgencySubmission?CreateDocument',
    type: 'POST',
    data: formData,
    async: false,
    cache: false,
    contentType: false,   // Important!
    processData: false,   // Important!
    success: function (returndata) {
      window.location = 'SubmissionThankYou.html';
    }
  });
  return false;
});

That’s it! It worked like a charm. And this is what the final result looks like:

FileUploadControl_Bootstrap

Of course, if you are able to use XPages, there are nice file upload controls there that you can use.

Free Software – Password Reset for Notes/Domino

Posted on September 24, 2014 by Karl-Henry Martinsson Posted in Administration, Bootstrap, HTML/CSS, IBM/Lotus, jQuery, Notes/Domino, Open Source, Software 7 Comments

Earlier this year I was asked to research some alternatives for a web-based password reset function at my work. One of the larger support burdens are users who forget the passwords, especially in the first few days after changing it. We have a 90 day password lifespan, then a new password need to be picked. Some users wait until the last minute, which usually is Friday afternoon right before they go home, making it very likely that they will forget the new password over the weekend. Another big group is auditors, who may come in every 6 months or so, and by then their passwords have of course already expired.

I first looked at some COTS solutions from HADSL (FirM) and BCC (AdminSuite). They were both very competent, and in addition have several other functions that I really would like to have in my environment (like synchronization between Domino Directory and Active Directory). However, as my company is in a cost saving phase, I was asked if I could build something myself, so I played around a little, and came up with a small and simple application.

The application contains two web pages. The first page (Setup) is where the user will setup the security questions used for password recovery as well as entering an external email address that they have access to even if locked out from the Domino account at work. This page is protected by regular Notes security, so the users need to set this up before they lose access to their account.

The second page (Request)is where the user can request the password to be reset. After entering their Notes name, the user is presented with one of the security questions. If the question as answered correctly, the user can now enter a new password. If the question is wrong, another of the questions is presented to the user. I am also using regexp to make sure that the password match the requirement our organisation have for password strength.

Both pages are built using Bootstrap (v3.2.0),  jQuery (v1.11.0), and for the icons I use Font Awesome (v4.2.0), all loaded from BootstrapCDN. I also use a few local CSS and Javascript files to handle older versions of Internet Explorer. The process steps were created using code by jamro and you can find the code here. By the way, Bootsnipp is a great resource to avoid having to invent the wheel again. There are hundreds of free snippets of code there to build neat Bootstrap functionality.

When the user fill out and submit the setup page, a document is created in a Notes database. When the user need to reset the password, the security questions and answers are retrieved from that document. To prevent unauthorised access to the Notes documents, they use Readers fields to prevent them from being visible to anyone but the signer of the agents running on the server.

This application can of course be updated with more functionality. Instead of allowing the user to pick a password, one could be generated by the server and sent through email to the address entered during setup. There are probably other things that can be done to adapt this application to the needs of your organization. And you probably want to change the logo on the pages to fit your organisation.

You can download the application here. It is licensed under Apache 2.0. I will try to get it up on OpenNTF.org soon as well.

Read the “About” page for instructions on installation and setup, as well as full license and attribution. Enjoy!

jQuery – A flexible way to show/hide sections

Posted on August 27, 2014 by Karl-Henry Martinsson Posted in Javascript, jQuery, Web Development Leave a comment

Yesterday Stephen Gainer blogged about a small Javascript problem he had.

Brilliant!  I gave my customer exactly what he wanted!  No muss no fuss!  I’m sure you see where I’m going with this.  As soon as this was done, my customer came back to me and said he needed four more of these.

My solution, which is terrible, was to duplicate the above four more times (me2Show, me2Hide, me3Show, me3Hide and on and on and …..)  Now I realize how stupid this is, but remember how I said above that there are certain simple things that I never really learned because I never had to?  Well this is one, and this is where I would like YOUR help!

I know there has to be some way to loop through all of my element ID’s with a simple piece of JavaScript, but I can’t for the life of me figure out how to do that.  Can anyone help me out here?

I commented on Stephen’s post and suggested that he use jQuery to easily loop though all elements with a specific class and add a listener function to them to detect a click. Since it is hard to get all information into a comment, I decided to post a simple code sample here instead. My code is easy to expand on, e.g by adding more sections.

There are of course many different ways to do this. You can of course use .toggle(), but I prefer to have better control of when to hide and show the sections. You can break out the lines $(“.mySection”).hide(); into a separate function and call it from the two locations. This is of course not saving anything in this particular code sample, but in more complex code it would make sense to break down the code into separate functions if they are called from multiple lines.

Hopefully this code will help someone, or inspire someone to start playing with jQuery. I like jQuery, as it easily integrates with classic Domino web applications, and even can be used with Xpages.

<html>
<head>
    <title>jQuery hide/show</title>
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> 
	<script>
		$(document).ready(function () {
		// Hide all sections when the page is first loaded
		$(".mySection").hide();
		// Setup all elements with class "myButton" to react on click
		$(".myButton").click( function() {
			// Check if the section is already displayed
			if ($(this).html()=="Hide") {
				// Hide the current section
				var sectionID = $(this).attr("data-showsection");
				$("#"+sectionID).hide();
				// Set the button label to "Show"
				$(this).html("Show");
			} else {
				// Hide all sections, using the class mySection
				$(".mySection").hide();
				// Set all button labels to "Show"
				$(".myButton").html("Show");
				// Show the section we want to display
				var sectionID = $(this).attr("data-showsection");
				$("#"+sectionID).show();
				// Set the button label to "hide"
				$(this).html("Show");
			}
		});
	});	
	</script>
</head>
<body>
    <button id="btnOne" class="myButton" data-showsection="sectionOne">Show</button>
    <div id="sectionOne" class="mySection" data-btnID="btnOne">This is the 1st section.</div>
    <br>
    <button id="btnTwo" class="myButton" data-showsection="sectionTwo">Show</button>
    <div id="sectionTwo" class="mySection" data-btnID="btnTwo">You are now seeing the 2nd section.</div>
    <br>
    <button id="btnThree" class="myButton" data-showsection="sectionThree">Show</button>
    <div id="sectionThree" class="mySection" data-btnID="btnThree">This is the 3rd section.</div>
    <br>
    <button id="btnFour" class="myButton" data-showsection="sectionFour">Show</button>
    <div id="sectionFour" class="mySection" data-btnID="btnFour">The 4th and last section.</div>
    <br>
</body>

Code snippet – jQuery

Posted on March 15, 2014 by Karl-Henry Martinsson Posted in HTML/CSS, jQuery, Lotusscript, Notes/Domino, Programming 6 Comments

This morning I was working on a web application, and I came up with a pretty neat and simple little solution. So I just wanted to share it, in case anyone else need something similar.

I have a webpage with an HTML form. Each input tag has an attribute called notesfield, matching the name of the field in Notes where the value is stored:

<div class="col-md-3">
    <label>First Name</label>
    <input class="form-control" type="text" notesfield="FirstName" value="" />
</div>
<div class="col-md-2">
    <label>Initial</label>
    <input class="form-control" type="text" notesfield="MiddleInitial" value="" />
</div>
<div class="col-md-3">
    <label>Last Name</label>
    <input class="form-control" type="text" notesfield="LastName" value="" />
</div>

Then I created a simple function that will call an agent on the Domino server, which will return all the fields on the specified document as JSON. This function is called after the HTML page is fully loaded.

function loadNotesFields(docunid) {
	var notesfieldname = "";
	$.ajax({
		url: "/database.nsf/ajax_GetNotesFieldFields?OpenAgent", 
		data: {"NotesUNID":docunid},
		cache: false
	}).done(function(data) {
		$('input[notesfield]').each(function() {
			notesfieldname = $(this).attr("notesfield");
			$(this).val(data[notesfieldname]);
		});
	});
}

The function is actually extremely simple, and here you can see the power of jQuery. What I do is to perform an Ajax call to a Domino URL, passing a UNID to the agent to use in the lookup. I set cache to false, to avoid the browser from reusing previously retrieved data (this is a good thing to do if the data retrieved can be suspected to change frequently).

The jQuery .ajax() functions returns the JSON in the data object, and when the call is done, the callback function loops through each input element with an attribute of notesfield, reads the value of said attribute and then sets the value of the input element to the corresponding Notes value.

The only thing left is to write the agent that will return the JSON. It could look something like this:

Dim urldata List As String

Sub Initialize
	Dim session As New NotesSession
	Dim webform As NotesDocument
	Dim db As NotesDatabase
	Dim doc As NotesDocument
	Dim urlstring As String
	Dim urlarr As Variant
	Dim urlvaluename As Variant
	Dim i As Integer
	Dim json As String

	Set webform = session.DocumentContext
	'*** Remove leading "OpenAgent" from Query_String
	urlstring = StrRight(webform.Query_String_Decoded(0),"&")
	'*** Create list of arguments passed to agent
	urlarr = Split(urlstring,"&")
	For i = LBound(urlarr) To UBound(urlarr)
		urlvaluename = Split(urlarr(i),"=")
		urldata(urlvaluename(0)) = urlvaluename(1)
	Next
	Set thisdb = session.CurrentDatabase
	'*** Create content header for return data
	Print "content-type: application/json"
	'*** Get Notes document baed on NotesUIND argument
	Set doc = db.GetDocumentByUNID(urldata("NotesUNID"))
	'*** Build JSON for all fields in document except $fields
	json = "{" + Chr$(13)
	ForAll item In doc.Items
		If Left$(item.Name,1)<>"$" Then
			json = json + |"| + item.Name + |":"| + item.Text + |",|+ Chr$(13)
		End If
	End ForAll
	'*** Remove trailing comma and line break
	json = Left$(json,Len(json)-2)	
	json = json + "}"
	'*** Return JSON
	Print json	
End Sub

Happy coding!

Excellent Bootstrap select plugin with great support

Posted on October 16, 2013 by Karl-Henry Martinsson Posted in Bootstrap, Frameworks, Javascript, jQuery, Web Development 1 Comment

For a Domino-based web application I am currently working on, I needed a nicer looking select box (drop down) than what Bootstrap offers out of the box. I did some searches and found a handful of free ones, most of them pretty good but not exactly what I wanted. Some did not handle different themes, other had additional functionality I did not want/need, etc. I probably been looking for a good alternative for 3 weeks by now.

Then the other day I found an inexpensive plugin at CodeCanyon. Custom Select for Twitter Bootstrap 3 is just $5 if you use it for a public site, or $25 if you use it on a site where you charge the users for access. It’s well worth it. The control is nice and clean, and very easy to use.

Custom Select for Twitter Bootstrap 3

Custom Select for Twitter Bootstrap 3

What really impressed me was how the author of the plugin, Lisa Stoz, fixed an issue I ran into. It was not a bug in the plugin, but I had a need to use custom tag attributes, and the plugin did not support that originally. The next day Lisa had a new version available with that functionality added. She also helped me with some additional questions that I had. I am very impressed with the quick response and the professional support.

I am new to CodeCanyon, but that site seems very nice. It contains a large number of jQuery and javascript plugins, Bootstrap themes and plugins, and much more. There is also a section with WordPress plugins, as well as a separate site for WordPress themes called ThemeForrest. That site also have other themes and templates. If you build websites, but like me is not a graphics genius, ThemeForrest is a great place to find themes or just inspiration for your site. The themes (as are the plugins) are very modestly priced, between $5 and $10 in most cases.

I have just started to scratch the surface of what’s available there, but I already think this is a great resource. The next time I need a plugin for Bootstrap, jQuery or WordPress, I will probably start at CodeCanyon.

Disclaimer: The links above uses an affiliate code, giving me a small credit at the site if you purchase anything.

Stack Exchange

profile for Karl-Henry Martinsson on Stack Exchange, a network of free, community-driven Q&A sites

Recent Posts

  • Domino 14 is now available
  • Domino 14 Early Access Program
  • Announced: Engage 2024
  • Integrate Node-RED with Notes and Domino
  • Notes and Domino v12 is here!

Recent Comments

  • Theo Heselmans on Announced: Engage 2024
  • Lotus Script Multi-thread Message Box [SOLVED] – Wanted Solution on ProgressBar class for Lotusscript
  • Viet Nguyen on Keep up with COVID-19 though Domino!
  • Viet Nguyen on Keep up with COVID-19 though Domino!
  • Mark Sullivan on Looking for a HP calculator? Look no further!

My Pages

  • How to write better code in Notes

Archives

  • December 2023 (1)
  • October 2023 (2)
  • September 2023 (1)
  • June 2021 (1)
  • April 2021 (2)
  • March 2021 (1)
  • August 2020 (3)
  • July 2020 (2)
  • April 2020 (2)
  • March 2020 (1)
  • December 2019 (2)
  • September 2019 (1)
  • August 2019 (2)
  • July 2019 (2)
  • June 2019 (3)
  • April 2019 (2)
  • December 2018 (1)
  • November 2018 (1)
  • October 2018 (5)
  • August 2018 (2)
  • July 2018 (3)
  • June 2018 (2)
  • May 2018 (1)
  • April 2018 (2)
  • March 2018 (1)
  • February 2018 (2)
  • January 2018 (4)
  • December 2017 (3)
  • November 2017 (2)
  • October 2017 (2)
  • September 2017 (1)
  • August 2017 (2)
  • July 2017 (6)
  • May 2017 (4)
  • February 2017 (1)
  • January 2017 (2)
  • December 2016 (2)
  • October 2016 (3)
  • September 2016 (4)
  • August 2016 (1)
  • July 2016 (2)
  • June 2016 (2)
  • May 2016 (3)
  • April 2016 (1)
  • March 2016 (4)
  • February 2016 (2)
  • January 2016 (4)
  • December 2015 (3)
  • November 2015 (2)
  • October 2015 (1)
  • September 2015 (2)
  • August 2015 (1)
  • July 2015 (5)
  • June 2015 (2)
  • April 2015 (2)
  • March 2015 (3)
  • February 2015 (2)
  • January 2015 (10)
  • December 2014 (1)
  • November 2014 (3)
  • October 2014 (3)
  • September 2014 (13)
  • August 2014 (6)
  • July 2014 (5)
  • May 2014 (3)
  • March 2014 (2)
  • January 2014 (10)
  • December 2013 (5)
  • November 2013 (2)
  • October 2013 (5)
  • September 2013 (4)
  • August 2013 (7)
  • July 2013 (3)
  • June 2013 (1)
  • May 2013 (4)
  • April 2013 (7)
  • March 2013 (8)
  • February 2013 (9)
  • January 2013 (5)
  • December 2012 (7)
  • November 2012 (13)
  • October 2012 (10)
  • September 2012 (2)
  • August 2012 (1)
  • July 2012 (1)
  • June 2012 (3)
  • May 2012 (11)
  • April 2012 (3)
  • March 2012 (2)
  • February 2012 (5)
  • January 2012 (14)
  • December 2011 (4)
  • November 2011 (7)
  • October 2011 (8)
  • August 2011 (4)
  • July 2011 (1)
  • June 2011 (2)
  • May 2011 (4)
  • April 2011 (4)
  • March 2011 (7)
  • February 2011 (5)
  • January 2011 (17)
  • December 2010 (9)
  • November 2010 (21)
  • October 2010 (4)
  • September 2010 (2)
  • July 2010 (3)
  • June 2010 (2)
  • May 2010 (3)
  • April 2010 (8)
  • March 2010 (3)
  • January 2010 (5)
  • November 2009 (4)
  • October 2009 (7)
  • September 2009 (1)
  • August 2009 (7)
  • July 2009 (1)
  • June 2009 (4)
  • May 2009 (1)
  • April 2009 (1)
  • February 2009 (1)
  • January 2009 (3)
  • December 2008 (1)
  • November 2008 (1)
  • October 2008 (7)
  • September 2008 (7)
  • August 2008 (6)
  • July 2008 (5)
  • June 2008 (2)
  • May 2008 (5)
  • April 2008 (4)
  • March 2008 (11)
  • February 2008 (10)
  • January 2008 (8)

Categories

  • AppDev (10)
  • Blogging (11)
    • WordPress (5)
  • Design (5)
    • Graphics (1)
    • UI/UX (2)
  • Featured (5)
  • Financial (2)
  • Food (5)
    • Baking (3)
    • Cooking (3)
  • Generic (11)
  • History (5)
  • Hobbies (10)
    • LEGO (4)
    • Photography (4)
  • Humor (1)
  • IBM/Lotus (178)
    • #Domino2025 (14)
    • #DominoForever (8)
    • #IBMChampion (46)
    • Administration (7)
    • Cloud (7)
    • CollabSphere (9)
    • Community (49)
    • Connect (33)
    • ConnectED (12)
    • Connections (3)
    • HCL (15)
    • HCL Master (1)
    • IBM Think (1)
    • Lotusphere (46)
    • MWLUG (25)
    • Notes/Domino (99)
      • Domino 11 (7)
    • Sametime (8)
    • Verse (14)
    • Volt (3)
    • Watson (6)
  • Life (8)
  • Microsoft (7)
    • .NET (2)
    • C# (1)
    • Visual Studio (1)
  • Movies (3)
  • Old Blog Post (259)
  • Personal (23)
  • Programming (84)
    • App Modernization (11)
    • Formula (4)
    • Lotusscript (47)
    • NetSuite (4)
      • SuiteScript (3)
    • node.js (4)
    • XPages (4)
  • Reviews (9)
  • Sci-Fi (4)
  • Software (24)
    • Flight Simulator (2)
    • Games (4)
    • Open Source (2)
    • Utilities (6)
  • Technology (37)
    • Aviation (3)
    • Calculators (2)
    • Computers (6)
    • Gadgets (7)
    • Mobile Phones (7)
    • Science (3)
    • Tablets (2)
  • Travel (7)
    • Europe (1)
    • Texas (2)
    • United States (1)
  • Uncategorized (16)
  • Web Development (50)
    • Frameworks (23)
      • Bootstrap (14)
    • HTML/CSS (12)
    • Javascript (32)
      • jQuery (23)
  • Prev
  • 1
  • 2
  • 3
  • Next

Administration

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

Tracking

Creeper
MediaCreeper
  • Family Pictures
© TexasSwede 2008-2014