Web page is not displaying the correct information

78 Views Asked by At

Problem

I've got a search results page that lists the search criteria elements and allows the user to click an element to remove that search criteria.

The first time clicking one of the criteria elements to remove it, everything works as expected.

However, the second time a criteria element is removed, the first removed element comes back.

Example

Search criteria: {topic: "abuse"}, {profession: "admin"}, {keywords: "animal"}

Now click the "topic" element to remove it, the results page now shows {profession: "admin"}, {keywords: "animal"}

Now click "keywords" to remove it, the page now incorrectly shows {topic: "abuse"}, {profession: "admin"}

The correct display at this point should be only a single tag {profession: "admin"}

Code

SearchController.Results()

<HttpPost>
<NoCache>
Function Results(ByVal model As SearchCriteria) As ActionResult

    Dim resultsModel As SearchResultsModel = New SearchResultsModel
    Dim searchQuery As IQueryable(Of [Class]) = Nothing
    Dim searchResults As List(Of [Class]) = Nothing
    Dim categoryValueQuery As IQueryable(Of CourseCategoryValue) = Nothing
    Dim query As IQueryable(Of [Class]) = Nothing
    Dim queries As List(Of IQueryable(Of [Class])) = New List(Of IQueryable(Of [Class]))

    model = RemoveCriteria(model)
    model.RemovalCriteria = String.Empty

    resultsModel.Criteria = model
    Return View(resultsModel)
End Function

SearchController.RemoveCriteria()

<NonAction>
    Function RemoveCriteria(ByVal model As SearchCriteria) As SearchCriteria

        Dim result As SearchCriteria = ObjectMapper.Duplicate(model)

        If Not String.IsNullOrEmpty(result.RemovalCriteria) Then
            Select Case result.RemovalCriteria.ToLower.Trim
                Case "title"
                    result.Title = String.Empty

                Case "keywords"
                    result.Keywords = String.Empty

                Case "healthtopic"
                    result.HealthTopic = String.Empty

                Case "city"
                    result.City = String.Empty

                Case "profession"
                    result.Profession = String.Empty

            End Select
        End If

        Return result

    End Function

Results.vbhtml

@Imports System.Reflection
@ModelType SearchResultsModel

@Code
    ViewData("Title") = "Results"
    Dim properties As List(Of PropertyInfo) = Model.Criteria.GetType.GetProperties.ToList
    Dim names() As String = {"keywords", "healthtopic", "profession"}
End Code

<h2>Results</h2>

@If (Not Nothing Is Model) AndAlso (Not Nothing Is Model.Results) Then
    @<h3>Displaying @Model.Results.Count of @Model.ResultCount classes</h3>
End If
@Using Html.BeginForm("Results", "Search", Nothing, FormMethod.Post, New With {.id = "removalForm"})
    @Html.Hidden("RemovalCriteria", String.Empty, New With {.id = "removalCriteria"})
    @<div>
        <span style="font-weight: bold;">Search Criteria  </span>
        @For Each name As String In names
        Dim prop As PropertyInfo = (From p In properties Where p.Name.ToLower = name Select p).FirstOrDefault
        Dim value As Object = prop.GetValue(Model.Criteria)
        If Not Nothing Is value Then
            value = value.ToString
            If Not String.IsNullOrEmpty(value) Then
            @<span class="criteriaTag" title="click to remove" onclick="submitRemovalForm('@prop.Name');">@prop.Name<span class="criteriaValue">@value</span></span>
            End If
        End If
            @Html.Hidden(prop.Name, value)
    Next
    </div>
End Using
<script type="text/javascript">
    function submitRemovalForm(removeTag) {
        $('#removalCriteria').val(removeTag);
        $('#removalForm').submit();
    }
</script>

So, any thoughts on why this could be happening?

1

There are 1 best solutions below

5
On BEST ANSWER

I am going to take a stab at how your code works, and if right, think I have your issue. It appears that for each criteria, you are outputting them in a hidden field. When you click a field, it adds that value to the hidden removeTag field then submits the form. On submit, it will exclude that field from the search query. If that's correct, here is what is going on:

You are not removing the property hidden input in the actual form. The form HTML markup probably looks something like the following:

<form>
  <input type="hidden" name="RemovalCriteria" value=""/>
  <input type="hidden" name="topic" value="abuse"/>
  <input type="hidden" name="profession" value="admin"/>
  <input type="hidden" name="keywords" value="animal"/>
</form>

So when you submit, you get something like the following on your form submit:

{
    RemovalCriteria:  "abuse",
    topic: "abuse", 
    profession: "admin",
    keywords: "animal"
}

When you next click remove on the "admin" tag, your form submission would look like:

{
    RemovalCriteria:  "admin",
    topic: "abuse", 
    profession: "admin",
    keywords: "animal"
}

Thus, abuse will be added back in. To prevent a previously removed tag from coming back, you would need to actually remove the hidden input associated with it as well:

<script type="text/javascript">
    function submitRemovalForm(removeTag) {
        $('#removalCriteria').val(removeTag);
        $('#removalForm').remove($("input[type='hidden'][name='" + removeTag + "']"));
        $('#removalForm').submit();
    }
</script>

Which should change your form markup to the following after clicking on the remove topic tag:

<form>
  <input type="hidden" name="RemovalCriteria" value="abuse"/>
  <input type="hidden" name="profession" value="admin"/>
  <input type="hidden" name="keywords" value="animal"/>
</form>

As to how this would impact your search (missing a property/tag combo) you might have to work out, it might not have any affect. But that appears to be why a removed tag is coming back.