Jon's Blog

.NET Development & More

ASP.NET MVC and jQuery UI Autocomplete

I wanted to document an easy way to add auto complete functionality to a search box in ASP.NET MVC using the jQuery UI Autocomplete widget. I've tried to make the code simple while still being left with a workable example.  This solution is a simplified version of this functionality I saw while watching the free ASP.NET MVC 3 video series from K. Scott Allen of Pluralsight.


Layout

First, below is the layout file we are using for this example.  Nothing special here.  Only thing to really note is the two optional sections: styles and scripts.  These are used on the View to add specific CSS and JavaScript needed for the example.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>ASP.NET MVC Example</title>
    @Styles.Render("~/Content/css")
    @RenderSection("styles", required: false)
</head>
<body>
    @RenderBody()

    @Scripts.Render("~/bundles/jquery")
    @RenderSection("scripts", required: false)
</body>
</html>

 

View

Now let's talk about the View.  The jQuery UI AutoComplete widget is being setup in the scripts @section by calling the jQuery UI autocomplete method and passing the properties I want to use. I am setting the source to the SearchAutoCompleter action method of my SearchExample Controller (see the next section).  I am also setting minLength to 2.  This means the call to the action method will not happen unless the user enters at least 2 characters.

<h2>Autocomplete Enabled Search</h2>

@using (Html.BeginForm())
{
    <input type="text" name="searchQuery" id="autocomplete" />
    <input type="submit" value="Search" />
}
    
@section scripts
{
    <script type="text/javascript" src="~/Scripts/jquery-ui-1.8.24.min.js"></script>
    <script type="text/javascript" src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
    
    <script type="text/javascript">
        $(document).ready(function () {
            $("#autocomplete").autocomplete({
                source: "@Url.Action("SearchAutoCompleter","SearchExample")",
                minLength: 2
            });
        });
    </script>
}

 

Controller

Below is an example of what you would have in your controller's action method.  I am showing a LINQ query that could be accessing a LINQ to SQL or Entity Framework repository, etc.  Here I am just getting 10 distinct items, but you can do whatever logic you need to do.  Notice that I am creating an anonymous type with one property named "label".  This is what the jQuery UI AutoComplete widget is expecting.  Note that label is case sensitive here.  Finally, the collection is returned as Json for the AutoComplete widget to process.

public class SearchExampleController : Controller
{
  public JsonResult SearchAutoCompleter(string term)
  {

      var myObjects = (from o in myRepository.MyClass
                      where o.ColumnToSearchOn.Contains(term)
                      select new{
                          label = o.ColumnToSearchOn
                      }).Distinct().Take(10);

      return Json(myObjects, JsonRequestBehavior.AllowGet);
  }
}

Resources

 

Jon's Blog | All posts tagged 'blob'

Jon's Blog

.NET Development & More

Using ASP.NET and GDI+ to Resize Uploaded Image

Below is some sample code I used to resize an uploaded image if the image does not meet the required width and height.  MAX_WIDTH and MAX_HEIGHT below are constants.  Change them as needed.  I am saving the resized image as a JPEG.  It is also a good idea to inform the user that their image was resized.  I removed that code to increase readability.

Note: In this sample the image is being saved to a database, but you could also save it to a file if you wanted to.

if (fileUpload.HasFile)
{
// Get uploaded image from upload control
System.Drawing.Image uploadedImage = System.Drawing.Image.FromStream(fileUpload.PostedFile.InputStream);

// Check width and height of image and resize if necessary
if (uploadedImage.Width > MAX_WIDTH || uploadedImage.Height > MAX_HEIGHT)
{
// Get the factor we must resize by
decimal heightFactor = Decimal.Divide(uploadedImage.Height, MAX_HEIGHT);
decimal widthFactor = Decimal.Divide(uploadedImage.Width, MAX_WIDTH);
decimal resizeFactor = Math.Max(heightFactor, widthFactor);

// Calculate the new height and width using the resize factor
int newHeight = Convert.ToInt32(uploadedImage.Height / resizeFactor);
int newWidth = Convert.ToInt32(uploadedImage.Width / resizeFactor);

Bitmap sourceBitmap = new Bitmap(uploadedImage);
Bitmap newBitmap = new Bitmap(newWidth, newHeight);
Graphics graphics = Graphics.FromImage(newBitmap);
MemoryStream memoryStream = new MemoryStream();

try
{
// Set quality settings and save to MemoryStream object as Jpeg
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.DrawImage(sourceBitmap, new Rectangle(0, 0, newWidth, newHeight));
newBitmap.Save(memoryStream, ImageFormat.Jpeg);

// Save to Business Object
bizObject.FileData = new Binary(memoryStream.ToArray());
bizObject.FileType = "image/jpeg";
bizObject.FileName = Path.GetFileNameWithoutExtension(fileUpload.FileName) + ".jpg";
}
catch (Exception)
{
throw;
}
finally
{
// Dispose of graphics objects
memoryStream.Dispose();
sourceBitmap.Dispose();
newBitmap.Dispose();
graphics.Dispose();
}
}
else
{
// Image size is correct, so save what was uploaded
bizObject.FileType = fileUpload.PostedFile.ContentType;
bizObject.FileName = fileUpload.FileName;
bizObject.FileData = new Binary(fileUpload.FileBytes);
}

// Other code removed for clarity
}