Repeater is not getting client-side updated Items

This is code for a user control I have a repeater which has data value attributes (data-camera-mac and data-checked). These values will be filled on the C# side:

repeaterCameras.DataSource = variableName;
repeaterCameras.DataBind();

I have an on-click C# method which reads the Items in the Repeater fine (method btnSave_Changes). Then I added some JavaScript which manipulates and shifts the HTML. The JavaScript works fine and manipulates the front end as expected. The JavaScript also changes the data value attributes. However, when the on-click event happens (btnSave_Changes), it prints the original set of Items in the Repeater as if no change happened from the JavaScript.

HTML:

<asp:Repeater ID="repeaterCameras" runat="server" >
    <ItemTemplate>
        <div class="<%# (bool)Eval("Checked") ? "row-fluid camera-row highlight-row highlight_selected_row" : "row-fluid camera-row highlight-row" %>" 
            data-camera-mac=<%# Eval("Mac") %> >

             <div class="highlight-bar"></div>

            <div id="divArrows" class="arrow-column camera-column-padding" 
                runat="server" visible="true" data-checked=<%# Eval("Checked")%> 
                data-camera-mac=<%# Eval("Mac") %> >
                <span id="spArrows" >
                    <i id="upArrow" class="icon-arrow-up icon-large" 
                        style="cursor:pointer;" onclick="upArrowClick(this)" ></i>
                    <i id="downArrow" class="icon-arrow-down icon-large" 
                        style="cursor:pointer;" onclick="downArrowClick(this)" ></i>
                </span>
            </div>

            <div class="check-box-column camera-column-padding">
              <span id="spCheckBox" runat="server">
                <i id="cameraSelectCheckBox" 
                    class="<%# (bool)Eval("Checked") ? "icon-ok icon-large" : "icon-check-empty icon-large" %>"   
                    style="cursor:pointer;" onclick="clickCheckBox(this)"
                    data-camera-mac=<%# Eval("Mac") %> ></i>
              </span>
            </div>

       </div>
    </ItemTemplate>
</asp:Repeater>

JavaScript:

function clickCheckBox(element) {
    var notHighlight = "row-fluid camera-row highlight-row";
    var highlight = "row-fluid camera-row highlight-row highlight_selected_row";
    if (element.className == "icon-check-empty icon-large"){
        element.className = "icon-ok icon-large";
        highlightRow(element.getAttribute("data-camera-mac"));
    }else if(element.className == "icon-ok icon-large"){
        element.className = "icon-check-empty icon-large";
        unHighlightRow(element.getAttribute("data-camera-mac"));
    } else {
        alert("Problem:  " + element.className);//TODO:  log error
    }
}

function highlightRow(mac){
    var currentClass = "row-fluid camera-row highlight-row";
    var newClass = "row-fluid camera-row highlight-row highlight_selected_row";
    var rowsList = document.getElementsByClassName(currentClass);
    for(var i = 0; i < rowsList.length; i++){
        if (rowsList[i].getAttribute("data-camera-mac") == mac) {
            var tempElem = rowsList[i].getElementsByClassName("arrow-column camera-column-padding")[0];
            tempElem.style.visibility = 'visible';
            tempElem.setAttribute("data-checked", "true");
            rowsList[i].className = newClass;
            break;
        }
    }
}

function unHighlightRow(mac){
    var newClass = "row-fluid camera-row highlight-row";
    var currentClass = "row-fluid camera-row highlight-row highlight_selected_row";
    var rowsList = document.getElementsByClassName(currentClass);
    for(var i = 0; i < rowsList.length; i++){
        if (rowsList[i].getAttribute("data-camera-mac") == mac) {
            var tempElem = rowsList[i].getElementsByClassName("arrow-column camera-column-padding")[0];
            tempElem.style.visibility = 'hidden';
            tempElem.setAttribute("data-checked", "false");
            rowsList[i].className = newClass;
            break;
        }
    }
}

function upArrowClick(element) {
    var current = element.parentNode.parentNode.parentNode;
    var previous = findPrevious(current);
    if (previous) {
        current.parentNode.insertBefore(current, previous);
    }
}

function findPrevious(element) {
    do {
        element = element.previousSibling;
    } while (element && element.nodeType != 1);
    return element;
}

function downArrowClick(element) {
    var current = element.parentNode.parentNode.parentNode;
    var next = findNext(current);
    if (next) {
        current.parentNode.insertBefore(next, current);
    }
}

function findNext(element) {
    do {
        element = element.nextSibling;
    } while (element && element.nodeType != 1);
    return element;
}

C#:

    protected void btnSave_Changes(object sender, EventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("btnSave_Changes");
        if (repeaterCameras == null || repeaterCameras.Items == null || repeaterCameras.Items.Count == 0)
            return;

        System.Diagnostics.Debug.WriteLine("repeaterCameras.Items.Count = " + repeaterCameras.Items.Count);
        for (int i = 0; i < repeaterCameras.Items.Count; i++)
        {
            System.Diagnostics.Debug.WriteLine("i = " + i);
            HtmlGenericControl div = repeaterCameras.Items[i].FindControl("divArrows") as HtmlGenericControl;
            string macStr = div.Attributes["data-camera-mac"].ToString();
            string checkedStr = div.Attributes["data-checked"].ToString();
            System.Diagnostics.Debug.WriteLine("data-camera-mac = " + macStr + ", data-checked = " + checkedStr);
        }

    }

Upvotes: 1

Views: 757

Answers (1)

invernomuto
invernomuto

Reputation: 10211

The problem is not the sorting of client side representation of repeater, but the inalterated sorting of items in the datasource;

This is the view state of a simple repeater:

/wEPDwULLTEwNjkxNzU2MzgPZBYCAgEPZBYCAgEPFgIeC18hSXRlbUNvdW50AgUWCgIBD2QWAmYPFQQQRW1waXJlIEJ1cmxlc3F1ZQlCb2IgRHlsYW4IQ29sdW1iaWEFMTAuOTBkAgIPZBYCZg8VBA9IaWRlIHlvdXIgaGVhcnQMQm9ubmllIFR5bGVyC0NCUyBSZWNvcmRzBDkuOTBkAgMPZBYCZg8VBA1HcmVhdGVzdCBIaXRzDERvbGx5IFBhcnRvbgNSQ0EEOS45MGQCBA9kFgJmDxUEE1N0aWxsIGdvdCB0aGUgYmx1ZXMKR2FyeSBNb29yZQ5WaXJnaW4gcmVjb3JkcwUxMC4yMGQCBQ9kFgJmDxUEBEVyb3MPRXJvcyBSYW1henpvdHRpA0JNRwQ5LjkwZGSThjyUMF+lfuzF5an9+yGiqSdlTXMozV4JAAW5zYmwsg==

Try to parse it in an online viewstate viewer like this

for this input:

enter image description here

the ouput will be this:

enter image description here enter image description here enter image description here

So after your client side manipulation the state of datasource will be unalterated, the simplest solution could be add an order attribute to your dataitems and change the value client side.

Upvotes: 1

Related Questions