Telerik ListView RadListViewItemDragDropEventArgs has an empty DestinationHtmlElement - c#

I'm implementing drag & drop with a Telerik RadListView (ASP.NET controls) and when I perform the drap and drop I don't get any data in the EventArgs of the server event (ItemDrop) that tell me where it was dropped i.e. from the DestinationHtmlElement inside the RadListViewItemDragDropEventArgs.
This is my control markup:
<telerik:RadListView ID="ListViewGallery" runat="server"
OnItemDrop="ListViewGallery_ItemDrop"
AllowPaging="true"
OnNeedDataSource="ListViewGallery_NeedDataSource"
AllowReorder="true"
DataKeyNames="FileId">
<ClientSettings AllowItemsDragDrop="true"></ClientSettings>
<ItemTemplate>
<div class="rlvI productItemWrapper">
<div style="width: 100px; height: 100px; background; background: url('<%#Eval("Photo") %>') no-repeat center center; background-size: contain;">
<telerik:RadListViewItemDragHandle ID="RadListViewItemDragHandle1" runat="server" ToolTip="Drag to organize" CssClass="move-item" />
</div>
</div>
</ItemTemplate>
<LayoutTemplate>
<div class="RadListView RadListViewFloated">
<div class="rlvFloated rlvAutoScroll">
<div id="itemPlaceholder" runat="server">
</div>
</div>
<telerik:RadDataPager ID="RadDataPager1" runat="server" PageSize="20">
<Fields>
<telerik:RadDataPagerButtonField FieldType="Numeric"></telerik:RadDataPagerButtonField>
</Fields>
</telerik:RadDataPager>
</div>
</LayoutTemplate>
</telerik:RadListView>
On the server side I just have this event handler:
protected void ListViewGallery_ItemDrop(object sender, RadListViewItemDragDropEventArgs e)
{
}
I thought it might be to do with not assigning the data correctly but I have made sure the DataKeyNames property of the list view is set.
Thanks in advance.
EDIT: I've just realised I have been missing a part of this. I want to drag it into itself to change the order of the items. The demo has the drop outside of the list.

OK so I figured it out.
To achieve this and to work out any css quirks I did the following:
I included a container inside the element with a class of rlvI (which you need to do for the drag and drop to work as per the Telerik website - see link in original post);
Inside this container I had to include a transparent image to take up the entire space and I floated this so as to remove it form the normal flow - I'm sure I could do this better but it is largely irrelevant for this exercise. You just need something inside it to drop "onto";
This internal image needs a unique Id so when it drops the event tells you where it was dropped;
Now the dropping works and I get the DestinationHtmlElement as the image client id of the one I dropped onto. Using this and the index of where it came from (from the DataItem.DataItemIndex of the event args) I can re order my list like so:
protected void ListViewGallery_ItemDrop(object sender, RadListViewItemDragDropEventArgs e)
{
if (e.DestinationHtmlElement.IndexOf("img-drop-zone") < 0)
{
return;
}
int newIndex = int.Parse(e.DestinationHtmlElement.Split('-').Last());
int oldIndex = e.DraggedItem.DataItemIndex;
ImagesList = MediaItem.MoveItem(ImagesList, (short)oldIndex, (short)newIndex);
ListViewGallery.Rebind();
}
The MoveItem method of MediaItem was fairly simple to write. If anyone is interested I can add it here but it essentially just re-adjusts the order property of the List items to reflect the move.

Related

onserverclick not firing for input of type date

I am building a web application in ASP.NET using webforms.
I have an input html element which I have set to run at server and I want to fire an event whenever the date is changed.
<input id="datePicker" class="form-control" style="display: inline; margin-left: 5px; width: 15%; text-align: center;" type="date" runat="server" onserverclick="Date_Changed"/>
I have the event in my codebehind:
protected void Date_Changed(object sender, EventArgs e) {}
However, the event is never fired.
Don't believe that server side click events can be wired up to a input that way (using the onserverclick).
I would consider dropping in a HTML button, say like this:
<button id="datePicker"
class="form-control"
style="display: inline; margin-left: 5px; width: 15%; text-align: center;"
type="date"
runat="server" onserverclick="Date_Changed" />
And even better yet, drop in a asp.net button.
If you drop in a input tag, then I don't think you can get the asp.net system to wire this up for you. You could I suppose write this:
(this is what a plane jane above button becomes:
<input onclick="__doPostBack('Button11','')"
name="Button11" type="button" id="Button11" value="button">
So you could try above - but using a "input" tag I don't believe will work, but try a HTML button as per above - that does allow "on server click".
Do keep in mind that if you drop in a asp.net text box, and set textmode = "date"?
Say like this:
<asp:TextBox ID="MyDateTest" runat="server" TextMode="date">
</asp:TextBox>
Then you see this:
So, above is a built in feature - you don't need any js, bootstrap, or anything at all.
but, you could add a "client" side click to your markup, as I posted a above the do post-back would (should) run your click event. However, it probably a whole lot better to not fight asp.net, since then you quite much hand coding a lot of HTML, and doing that means you quite much toss out most of the features of why you would use asp.net in the the first place (that means to take advantage of all the built in controls, and the pre-processing of those controls for you).

Link button inside a Repeater control, how to change the background/foreground color of clicked item?

I would like to show list of days in week (dynamic, some time all days, sometime only 2-3)
and then user will click on day and refresh the same page.
Above functionality is achieved by below code.
<asp:Repeater ID="DayList" Runat="server">
<ItemTemplate>
<asp:LinkButton ID="lbDayList" Runat="server" CommandName='<%# DataBinder.Eval (Container.DataItem, "wkdayVal")%>'
OnCommand="lbDayList_click"
DataBinder.Eval(Container.DataItem, "wkday")%>
</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
I want to show the clicked day in different color!! Please help in achieving this functionality!
Have you considered creating a styles.css page and using the CssClass="" attribute of your LinkButton?
In your styles.css file you would have something like the following:
.Visited
{
color: #fff;
background: inherit;
text-decoration: none;
}
Then your link button's css attribute would use something like
CssClass="visited"
You'll want to do this on the PreRender portion of your Repeater so set the Repeater's OnPreRender attribute to Repeater_OnPreRender. Then in your codebehind create a function like so
protected void Repeater_OnPreRender(object sender, EventArgs e)
{
//get the index of the selected item
//loop through your items colleciton until you find the item with the corresponding index
//find your link button
//set your link button's css attribute.
}
The reason you would perform this in the PreRender stage is because your repeater already has the data loaded into it and the HTML that is passed back to the web browser has not yet been created.
Hope this helps. GS

ASP.Net Checkboxlist Background color

I have a checkboxlist on aspx
<asp:CheckBoxList ID="cblCalendarFilter" runat="server" />
I add the listItems from code behind.
newCkItm = new ListItem();
newCkItm.Text = childrenFoldersData[i].Description.Trim();
newCkItm.Value = childrenFoldersData[i].Id.ToString().Trim();
newCkItm.Selected = true;
I can add the background of the ListItem by
newCkItm.Attributes.Add("style", "background-color:Red;");
The colors will be different from one item to another and the name of the item will also be different. So, the problem is the background color is only covering the text length. The background color is not aligned for all Items. I checked with the inspector and found out that..
The background color style is applying to <span> surrounding the text
All spans are inside the <td>.
I am wondering if there is a way to apply that style to <td> without much effort. I'd rather not use jquery and javascript by searching the name.
Is there any way to do that??
I have tried and found this solution & it worked for me.
Just try to give padding-right
for example:
newCkItm.Attributes.Add("style", "background-color:Red;padding-right:30px");
Instead of adding a style attribute to each item, and because you mentioned each item needs a different background colour, I'd add an id attribute:
newCkItm.Attributes.Add("id", "alpha");
That way you can keep all your styles separate from your code and not have to recompile, etc. every time you need to tweak the CSS.
With the <asp:CheckBoxList /> the CSS itself would look something like this:
#cblCalendarFilter {
border:none;
border-collapse:collapse;
}
#cblCalendarFilter td {
padding:0;
}
#cblCalendarFilter span {
display:block;
padding:2px;
}
#cblCalendarFilter #alpha {
background:red;
}
#cblCalendarFilter #beta {
background:yellow;
}
Hopefully making the span block-level will fix the issue you had with the background colour only covering the text length.
How about if you use a Repeater which has tr/td with CheckBox inside it and do the logic on the ItemDataBound event where you can retrieve the td:
<table>
<asp:Repeater ID="rpt" runat="server" OnItemDataBound="rpt_ItemDataBound">
<ItemTemplate>
<tr>
<td id="myTd" runat="server">
<asp:CheckBox runat="server" ID="myCheckBox" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
I think there is no other way, you have to individually access the element and assign the css to items. I tend to use foreach loop, access the item and add attributes. TBH, I would stay with checkboxlist compared to repeater, unless I need some extra functionality

Selecting an element without an Id

I'm trying to select an element from my webpage...
I have inserted a control into my page and i need to set some values an element inside the control at pageload from c# code.. The thing is, as soon as I insert the control into the page... A prefix is appended to the id name... Because of that new name, my css definition won't be appended...
Is there any way to access this element from C# without the need to make it an Id?
Edit: To clarify what Im trying to do here. Im trying to make a generic control, which gets a width and height set to it's parameters. I need to set this manually to the element by adding a style attribute. I can't make the element an id, because this will stop the possibility of making it generic.
This is whats inside of the control... the fact is, I need the imageRotatorDiv to be a class instead of an id. Otherwise i can't use multiple image rotators on one page.
But how can I select a class in a page from c# code? Is it possible?
<div id="imageRotatorDiv" runat="server">
<div class="imageRotator">
<asp:Repeater ID="rprImages" runat="server">
<ItemTemplate>
<asp:Image ID="imgItem" runat="server" />
</ItemTemplate>
</asp:Repeater>
</div>
</div>
you can define your style to a class name instead of id.
<asp:TextBox ID="MyText" CssClass="someclass" runat="server" />
html output
<input type="text" id="Something_MyText" class="someclass" />
css
.someclass { border:solid 1px red; }
In JQuery :
$("div[id$=MyDiv]").addClass("myDiv")
And you just need to define the myDiv CSS class. Or, to modify directly the style :
$("div[id$=MyDiv]").css("font-size", "14px");
JQuery details

How Do I Get a Dynamic Control's Value after Postback?

I have a listview that adds controls in the ItemDataBound Event. When the postback occurs, I cannot find the new controls. After a bit of research, I found that ASP .NET needs these controls created every time, even after postback. From there I moved the function to bind the ListView outside of the if (!Page.IsPostBack) conditional. Now I get the dynamic controls values but the static controls I have are set to their defaults. Here is a sample of what I am trying to accomplish:
For brevity, I left some obvious things out of this example.
<asp:ListView runat="server" ID="MyList" OnItemDataBound="MyList_ItemDataBound">
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceholder" />
</LayoutTemplate>
<ItemTemplate>
<asp:PlaceHolder runat="server" ID="ProductPlaceHolder">
<asp:TextBox runat="server" ID="StaticField" Text="DefaultText" />
<asp:PlaceHolder ID="DynamicItems" runat="server" />
</asp:PlaceHolder>
</ItemTemplate>
</asp:ListView>
and here is the codebehind:
protected void MyList_ItemDataBound(object sender, System.Web.UI.WebControls.ListViewItemEventArgs e) {
PlaceHolder DynamicItems = (PlaceHolder)e.Item.FindControl("DynamicItems");
DynamicItems.Controls.Add(textbox);
}
So, like I said, if I only databind when Page != PostBack then I cant find my dynamic controls on postback. If I bind every time the page loads then my static fields get set to their default text.
Try moving the data binding of the ListView into the OnInit() event.
Very similar question (instead of populating a ListView the guy is generating a set of buttons). Briefly, you'll find that you have to store the items in the list in your Viestate - than fish it out on Postback and re-populate the list.
Note that this solutions implies dropping data-binding (which you might not wanna do for others reasons).
Hope it helps.

Categories