You are currently browsing the category archive for the ‘jQuery’ category.

Recently I had a scenario where I needed to pass a value to a web service when a user selected an option in a drop down list. I had the drop down in a Razor view and when an item was selected an associated value needed to be passed to a web service as a parameter. However the value to be passed was not the id or value in the drop down but a different value associated with the selected item. So I needed a way to store this associated value in the drop down along with each displayed item.

In the database each item had 3 values associated with it – the database id, short name (for display), and long name (for passing to a service). The drop down needed to show the short name, so I populated the drop down with the database id as the value and the short name as the text.

As an example the drop down had values such as Cortina, Boxster, and Viper. When Cortina is seleted “Ford Cortina 1979 Blue” needed to be passed to the service. The solution I came up with was to store the long name as a data dash attribute in each item in the drop down. So here’s the data:

CARID SHORT_NAME LONG_NAME
1     Viper     Dodge Viper 1982
2     Boxster   Porsche Boxster 2009 Black
3     Cortina   Ford Cortina 1979 Blue

I added a JsonResult method on the Controller to return an anonymous object with the 3 properties that I wanted:


public class VehicleController : Controller
{
    // etc.
    public JsonResult GetSubTypesForTypeType(string typeTypeName)
    {
        var cars = repository.GetTypeWithSubTypes(typeTypeName);

        return cars == null
        ? Json(new object[0], JsonRequestBehavior.AllowGet)
        : Json(cars.SubTypes.OrderBy(s => s.Name).Select(
            s => new { s.SubTypeID, s.Name, s.Description }).ToArray(),
            JsonRequestBehavior.AllowGet);
    }
    // etc.
}

Here’s the code I use to create the drop down:

    <div class="editor-field">
        @Html.DropDownListFor(model => model.CarID,
            new SelectList(ViewBag.Cars, "Value", "Text", "1"))
        @Html.ValidationMessageFor(model => model.CarShortName)
    </div>

Then in js:

Populate the drop down:


// populate the cars drop down when the select list is available
if ($('select#SubTypeID').length) {
    var carsSelect = $('select#SubTypeID');
    var carsList = populateCarsList("CARS");
    var carsListHtml = createCarsSelectList(carsList);
    carsSelect.html('');
    carsSelect.append(carsListHtml);
    $('#SubTypeID').change(function (e) {
        clearFormData();
    });
}

Call a function to get the subtypes (cars) via an ajax call:

function populateCarsList(typeTypeName) {
    var carsList;
    $.ajax({
        url: '/Vehicle/GetSubTypesForTypeType',
        data: { typeTypeName: typeTypeName },
        async: false
    }).done(function (data) {
        carsList = data;
    }).error(function (msg, url, line) {
            alert("Error - error message: " + line);
    });

    return carsList;
}

Function to create the select list with the added description as a “data-*” attribute:

function createCarsSelectList(selectData) {
    var html = '',
    len = selectData.length,
    selected,
    description;

    for (var i = 0; i &lt; len; i++) {
        // "Viper" should be selected by default
        if (selectData[i].Name.toLocaleUpperCase() === "VIPER") {
            selected = ' selected="selected" ';
        } else {
            selected = '';
        }

        // Add the description (as a "data-" attribute), some are null
        if (selectData[i].Description != null) {
            description = selectData[i].Description;
        } else {
            description = '';
        }

        html += '<option value="' + selectData[i].SubTypeID + '" data-description="' + description + '"' + selected + '>' + selectData[i].Name + '</option>';
    }

    return html;
}
Advertisements

If you’re reading this you might be wondering why in the name of all that’s good and holy would you want to use the same fields in different sections of an accordion control? Surely the whole point of an accordion is that you display different content in different sections? Well read on…

I needed to do exactly this very recently, the main reason being that the screen I was working on would fit with corporate design guidelines. I’m currently working on a large C# .Net MVC3 application that utilises Razor, jQuery, and knockout.js on the front end. The interface is made up of a main partial view containing several tabs that present the data. The company has a corporate interface team that defines the GUI standards that every application must adhere to. Some of the tabs have accordions that show different information in each section, but the tab I’m currently working on has an accordion with 2 sections, each one containing the same fields except one. To me it doesn’t make sense to use an accordion for this, just use a radio button to toggle between the 2 differing fields. However I was overruled on this and told I must use the accordion as it fits in with the other tabs.

So to do it I initially started playing with the code below:

$('#accordion').append($('#div1')).accordion('destroy').accordion()

But this wouldn’t work for me at all, it kept adding a new section to the end of the accordion rather than recreating it. So I started to look at another approach and came up with the jQuery append() method which worked a treat.

Here’s the rendered Razor code:

<div id="accordion">
  <h3 class="acc-header"><a href="#">First header</a></h3>
  <div>
    <fieldset id="input-fields">
      <label for="defaultStudyEvent_GroupName">Group Name</label>
      <input id="defaultStudyEvent_TimePoints" name="defaultStudyEvent.TimePoints" type="text" value="" />
    </fieldset>
  </div>
  <h3 class="acc-header"><a href="#">Second header</a></h3>
  <div>
    (Move "input-fields" fieldset to here when "Second header" is clicked)
  </div>
</div>

Then in jQuery do the following:

$(document).ready(function () {
  $('#accordion').accordion();
  $('.acc-header').click(moveFields);

  function moveFields() {
    $(this).next().append($('#input-fields'));
  }
});

So this approach worked well for my situation. It will move the fields rather than create copies which is what I wanted. It’s suitable for an accordion if you have the same fields in different sections and don’t want to have duplicate fields all over the shop. It will also work in other scenarios if you just want to move fields dynamically depending on your particular scenario. Other variations of this approach are appendTo() and prepend() which do slightly different things.

%d bloggers like this: