Convert C# to clientside Javascript - c#

I have an Asp.Net page with a list of options accompanied by a checkbox in a ListView control. I have applied Paging using the paging control. However I want to maintain the status of the checkboxes across the various paged pages of the ListView. I have done this with the following code
private List<int> IDs
{
get
{
if (this.ViewState["IDs"] == null)
{
this.ViewState["IDs"] = new List<int>();
}
return (List<int>)this.ViewState["IDs"];
}
}
protected void AddRowstoIDList()
{
int checkAction = 0;
foreach (ListViewDataItem lvi in lvCharOrgs.Items)
{
CheckBox chkSelect = (CheckBox)lvi.FindControl("chkSelect");
if ((((chkSelect) != null)))
{
int ID = Convert.ToInt32(lvCharOrgs.DataKeys[lvi.DisplayIndex].Value);
if ((chkSelect.Checked && !this.IDs.Contains(ID)))
{
this.IDs.Add(ID);
checkAction += 1;
}
else if ((!chkSelect.Checked && this.IDs.Contains(ID)))
{
this.IDs.Remove(ID);
}
}
}
}
protected void lvCharOrgs_ItemDataBound(object sender, ListViewItemEventArgs e)
{
ListViewDataItem lvi = (ListViewDataItem)e.Item;
if ((lvi.ItemType == ListViewItemType.DataItem))
{
// Find the checkbox in the current row
CheckBox chkSelect = (CheckBox)lvi.FindControl("chkSelect");
// Make sure we're referencing the correct control
if ((chkSelect) != null)
{
// If the ID exists in our list then check the checkbox
int ID = Convert.ToInt32(lvCharOrgs.DataKeys[lvi.DisplayIndex].Value);
chkSelect.Checked = this.IDs.Contains(ID);
}
}
if (Profile.proUserType == "basic")
{//basic account so no choice of charity
((CheckBox)e.Item.FindControl("chkSelect")).Checked = true;
((CheckBox)e.Item.FindControl("chkSelect")).Enabled = false;
}
}
Now I have a CustomValidator control which checks to ensure between 3 & 5 records have been selected. If this is true the page is valid and processed. If it is not the case (eg less than 3 or more than 5) the page is Invalid and the CustomValidator throws up a label to notify of this fact.
I use the following code on the serverside to implement this.
protected void lvCharOrgsValidator_ServerValidate(object source, ServerValidateEventArgs args)
{// Custom validate lvCharOrgs
//update selected rows
AddRowstoIDList();
//get count and verify is correct range
int counter = this.IDs.Count;
args.IsValid = (counter >=3 && counter <=5) ? true : false;
}
This all works fine except I need to implement a 'ValidatorCallout' extender from the AJAX Control Toolkit. However this doesn't work with CustomValidators unless they implement clientSide validation. Thus I need to convert the 'lvCharOrgsValidator_ServerValidate' method to a clientside JavaScript function.
Hope this clarifies my requirements.

What does the following do?
AddRowstoIDList();
Something like the following is a start, but will need more details on the above method to provide a working answer
function validateRowCount(sender, args) {
//update selected rows
AddRowstoIDList(); // Does this add row indexes to an array?
//get count and verify is correct range
var counter = IDList.length;
args.IsValid = (counter >=3 && counter <=5);
}
It might be worth looking at Script# for a longer term solution, if you're planning on doing a lot of conversion.
EDIT:
now I can see the AddRowstoIDList() method, to do this on the client-side will be slightly different. Firstly, get a reference to the DOM element that is rendered for lvCharOrgs. Probably the most straightforward way to do this in vanilla JavaScript would be to put the JavaScript function in the page and use the server tags to get the rendered ClientID.
function validateRowCount(sender, args) {
var lvCharOrgs = document.getElementById('<%= lvCharOrgs.ClientID %>');
var checkboxes = lvCharOrgs.getElementsByTagName('input');
var len = checkboxes.length;
var counter = 0;
for(var i =0; i < len; i++) {
if (checkboxes[i].type == "checkbox" && checkboxes[i].checked) counter++;
}
args.IsValid = (counter >=3 && counter <=5);
}
Should work something like this - Working Demo
add /edit to the URL if you want to see the code

If you change int to var, your code is valid JavaScript. (But since it depends on other functions and objects you need to convert those as well.) Also if you're using the c# 3.5 compiler it will stay valid C# even with var instead of int.

Probably not what you want, but there is jsc:
"Web 2.0 hype? Want build better web
sites, but javascript is too hard? No
real IDE? Maybe you should try jsc.
The web app can be built within Visual
Studio 2008 or any other c# compliant
IDE, and then the application
magically appears. You should think of
it as a smart client. Precompile your
c# to javascript with jsc! As an
option instead of using IIS and
asp.net, you could get away by using
apache, with mysql and php."

Have a look at this article. It applies to asp.net mvc, but it also covers some basics and you might be able to do something similar for asp.net. In particular, you might find the jquery remote validation attributes shown in the article useful for what you intend to do.

SharpKit converts C# to client side javascript.
https://sharpkit.github.io/

Well, you can always include your own javascript with custom validators. Here is a link to an article that introduces adding javascript to a validator. You just have to write your own javascript, really.

I heard about a cross-compiler from c# (or was it IL?) to JavaScript but unfortunatly do not remember the name anymore, but a google-search turned up stuff like this: http://jsc.sourceforge.net/

Related

Generic list of Objects, passed through a HTML text writer class to output html. Now trying to implement paging

I have a list of objects which have been taken form a stored procedure. I then take this list pass it through a method I created which wraps it in HTML and then out puts to the webform.
I'm looking to create paging for this list. I have stored the list in a session and have two buttons ( next and previous ) I'm using LINQ to skip and take form the list on each button click.
Button Click
protected void lnkNext_Click(object sender, EventArgs e)
{
ListOfAdvertAndUsers = (List<Advert_User>)Session["list"];
var list = from item in ListOfAdvertAndUsers select item;
var pgNo = 1;
var pgRec = 6;
list = list.Skip(pgRec * pgNo).Take(pgRec).ToList();
ListOfAdvertAndUsers = list.ToList();
PopulateData(ListOfAdvertAndUsers);
}
I don't have enough rep to make a comment so I will just post my comments as an answer.
I presume that you are using Asp.Net WebForms, so how are you outputting the final html, Response.Write or setting Text on a Literal?
But if you are using WebForms, would it not be easier to use some of the builtin Controls. I donĀ“t exactly know how your data looks like, but maybe a GridView would be a good solution as it has builtin support for paging. Here is an example from MS on how it can be used: http://www.asp.net/web-forms/overview/presenting-and-managing-data/model-binding/sorting-paging-and-filtering-data
Not a direct answer, but you're overwriting queries and lists, which seem to convolute the code unnecessarily. Your method could be simplified to:
protected void lnkNext_Click(object sender, EventArgs e)
{
ListOfAdvertAndUsers = (List<Advert_User>)Session["list"];
var pgNo = 1; // don't you need to increment the page number somewhere?
var pgRec = 6; // should this be defined somewhere other than this method?
var page = ListOfAdvertAndUsers.Skip(pgRec * pgNo).Take(pgRec);
PopulateData(page);
}
Perhaps that will help you determine what the real problem is...

How to make a label blink in asp.net in codebehind

I would like for a label to blink or flash in my ASP.NET C# codebehind. Can someone please tell me how I can do that? Here is the code that I have tried:
label1.Attributes.Add("style", "text-decoration:blink");
Using this the label never blinks or flashes. I want to use C# in the codebehind, not JavaScript or HTML.
The "blink" setting for text-decoration has been depreciated, and browsers are not required to support it. Internet Explorer and Chrome to not. Not sure about the others.
Maybe there is some neat jQuery, i don't know. I have used this javascript in my last ASP.NET project:
var g_blinkTime = 400;
var g_blinkCounter = 0;
var g_maxBlinkCount=4;
var g_currentBlinkCount=0;
function blinkElement(elementId){
var blinkingElement=document.getElementById(elementId);
if(blinkingElement != null){
if(g_currentBlinkCount==g_maxBlinkCount){
g_currentBlinkCount=0;
blinkingElement.style.visibility = 'visible';
return;
}
if ( (g_blinkCounter % 2) == 0 ){
blinkingElement.style.visibility = 'visible';
}else{
blinkingElement.style.visibility = 'hidden';
}
if ( g_blinkCounter < 1 ){
g_blinkCounter++;
}
else{
g_blinkCounter--
}
window.setTimeout('blinkElement(\"' + elementId + '\")', g_blinkTime);
g_currentBlinkCount++;
}
}
Since that was an ASP.NET-Ajax app i've used this to register the script for a label:
AjaxControlToolkit.ToolkitScriptManager.RegisterStartupScript(UpdFilterPanel, typeof(string), "GrdChargeFilterInfoBlink", "blinkElement('" & LblInfo.ClientID & "');", True);
But you can also use ClientScriptManager.RegisterStartupScript instead without Ajax.
Edit according to your update: "I want to use C# in the codebehind, no JavaScript or HTML"
Blinking controls is done by the client's browser, so the server is not responsible for it. As mentione by James you cannot use text-decoration:blink since that is not supported by IE and others. So i don't know a different approach than javascript.

How to Check if ListBox is Empty on Client-Side

I created a javascript confirm as below.
<script Type="Text/Javascript">
function CheckListBox(lvi)
{
if(lvi == "")
{
if(confirm("Are you sure?"))
{
return true;
}
else
{
return false;
}
}
}
</script>
I need to test if the ListBox.Items control is empty... I already made reference on my aspx page
<script language="javascript" type="text/javascript" src="/JS/confirm.js"></script>
I want to know how to call it on my aspx.cs page . . . So I can pass the parameter:
string oi = Listbox_Clubes.Items.Count.ToString();//Its the parameter I want to pass
See this link for how to execute javascript from code behind
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(), "CheckListBox(" + Listbox_Clubes.Items.Count.ToString() + ");", false);
}
Note: you must add a ScriptManager control in aspx page.
For your javascript, you can get the value without the code-behind (this assumes the script code is in the same page, in order to get the client ID):
<script>
function ClickListBox() {
if ($("#<%= Listbox_Clubes.ClientID %>").val() === null) {
if (confirm("Are you sure?")) {
return true;
}
else {
return false;
}
}
}
</script>
Similarly, you don't use javascript to validate on the server side. The code you posted will return all items in the ListBox. Here is one way to get the count of the number of selected items (I'm using .ToString() based on the OP code example):
string oi = Listbox_Clubes.Items.Cast<ListItem>().Where(i => i.Selected).Count().ToString();
However, there is no reason why you would get this value and pass it back to the client-side to do validation (what it sounds like you want to do in your post). Mainly because this involves a post-back, and client-side validation, by its nature, should occur before post-back. Also, you will still need to do server-side validation, even when you have client-side validation.
Related: in the code-behind, you can test to see if anything is selected by:
bool hasValue = Listbox_Clubes.SelectedItem != null;
The .SelectedItem returns the selected item with the lowest index in the list control. When nothing is selected, this value is null... so you know if the value isn't null, then at least one item was selected.
If you want to require that they choose at least one item, you can use a RequireFieldValidator and let that handle both validations. If you haven't done much with ASP.NET validators, that would be one good thing to read up on.
It sounds like you probably should read more about client-side validation and server-side validation and how to use them... because it seems like you are mixing them up.
The count code is a modified version of code in ASP:ListBox Get Selected Items - One Liner?

C# DataGridView CellClick Returning Previous Index on Click

I have the following code:
private void dgv_Checks_CellClick(object sender, DataGridViewCellEventArgs e)
{
DoThis();
if (e.RowIndex < 0)
return;
if (dgv_Checks.CurrentCell.OwningColumn.Name == "CopyBalance")
dgv_Checks.Rows[e.RowIndex].Cells["CheckAmountColumn"].Value = dgv_Checks.Rows[e.RowIndex].Cells["AccountBalanceColumn"].Value;
// ****** THIS IS WHERE I AM HAVING ISSUES ******
if (e.RowIndex > -1 && dgv_Checks.Columns[e.ColumnIndex].Name == "SearchColumn")
{
var acctno = dgv_Checks.Rows[e.RowIndex].Cells["AccountNumberColumn"].Value.ToString().Trim();
if (acctno.Length == 7)
{
var acctname = GetAccountName(acctno);
if (acctname.Trim().Length > 0)
{
dgv_Checks.Rows[e.RowIndex].Cells["NameColumn"].Value = acctname;
dgv_Checks.Rows[e.RowIndex].Cells["AccountBalanceColumn"].Value = GetAccountBalance(acctno);
}
else
{
AccountSearchScreen(dgv_Checks.CurrentRow);
}
}
else
{
AccountSearchScreen(dgv_Checks.CurrentRow);
}
}
dgv_Checks.Rows[e.RowIndex].Cells["CheckAmountColumn"].Value = dgv_Checks.Rows[e.RowIndex].Cells["AccountBalanceColumn"].Value;
}
When it reaches this line:
if (e.RowIndex > -1 && dgv_Checks.Columns[e.ColumnIndex].Name == "SearchColumn")
I am getting back the previous cell's index so I am always 1 click behind. Am I not using the right event? I just want to capture a button click and only that one in the "SearchColumn".
Thanks as usual.
If I recall correctly, it has nothing to do with the handler code, and something to do with other page events, master pages, validation, etc. Something is hijacking your request somewhere in the .net framework that causes it to get delayed, but I can't remember where...
Take your gridview and datasource, and put them in a separate file with no master pages or other confounding factors and see if the problem goes away.
If it is now working normally, either add in components from your original page until you can replicate the problem again, or go back to your original page and step through everything it does. This has happened to me at least twice, and all I can remember is that it's something that seems completely unrelated.
Not only have I provided a fairly useless answer, but I've demonstrated once again why I should really keep a (b)log of this crap...

Persisting User Input for Dynamic Control in SharePoint Web Part

Edit at bottom with solution
I've seen a similar question to this posted before and have tried the suggestions, but I must be missing something. My basic problem is this: I have a select box where the user can select a filter which may or may not have constraints built into it (requires the user to input further data so the filter knows how to filter). Since it's unknown just how many constraints will exist for the filter, I'm trying to load them in dynamically and add them to a placeholder panel that I have. The correct number of constraints load just fine and dandy, but when the user inputs text and hits submit, after the page reloads none of the values persist. Here's the appropriate code (I can provide more if needed):
I have these as class variables for my Web Part:
Panel constraintPanel;
HtmlInputText[] constraints;
Label[] constraintLabels = null;
Inside an override CreateChildControls I initialize the panel:
constraintPanel = new Panel();
I build in the dynamic input boxes in an overridden OnPreRender (Note: I've heard people say to do it in OnInit, OnLoad, or OnPreRender, but OnPreRender is the only one that doesn't make the whole Web Part error out):
protected override void OnPreRender(EventArgs e)
{
buildConstraints();
base.OnPreRender(e);
}
private void buildConstraints()
{
if (!viewSelect.SelectedValue.Equals(INConstants.NoFilterOption))
{
string[,] constraintList = docManager.GetFilterConstraints(viewFilterSelect.SelectedValue);
if (constraintList != null)
{
this.constraints = new HtmlInputText[constraintList.Length / 2];
this.constraintLabels = new Label[constraintList.Length / 2];
for (int constraintCount = 0; constraintCount < constraintList.Length / 2; constraintCount++)
{
Label constraintLabel = new Label();
constraintPanel.Controls.Add(constraintLabel);
constraintLabel.Text = constraintList[constraintCount, 0];
this.constraintLabels[constraintCount] = constraintLabel;
HtmlInputText constraint = new HtmlInputText();
constraintPanel.Controls.Add(constraint);
constraint.ID = "constraint_" + constraintCount;
constraint.MaxLength = 12;
constraint.Style.Add("FONT-FAMILY", "Verdana");
constraint.Style.Add("FONT-SIZE", "11");
this.constraints[constraintCount] = constraint;
}
}
}
}
And then finally inside an overridden RenderWebParts I have (note: I've also tried looping through the arrays constraints and constraintLabels to render the controls, but it made no difference):
...
constraintPanel.RenderBeginTag(output); // not sure if this is needed
if (constraints != null && constraints.Length > 0)
{
foreach (Control tempControl in constraintPanel.Controls)
{
if (tempControl is Label)
{
output.WriteLine("<tr>");
output.WriteLine("<td width='2%' nowrap><font class='search-header'>");
tempControl.RenderControl(output);
output.WriteLine(" ");
}
else if (tempControl is HtmlInputText)
{
tempControl.RenderControl(output);
output.WriteLine("</td>");
output.WriteLine("<td width='*' nowrap></td>");
output.WriteLine("</tr>");
}
}
}
constraintPanel.RenderEndTag(output); // not sure if this is needed
...
I appreciate any help, as this is truly driving me crazy.
Edit with solution:
I've been able to get it working. I needed to override the OnLoad event and wrap my calls from there in a try-catch block. For some reason the initial page load throws an exception when trying to run, which causes the entire page to not display. I also forgot to add my constraintPanel to the Controls list.
Here's the code in OnLoad for information's sake:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
try
{
viewsBuildConstraints();
}
catch (Exception)
{
}
}
Try marking your webpart with the INamingContainer interface and make sure to give all controls an ID. Furthermore, HtmlInput COntrols do not have a viewstate i believe, which would cause them to "forget" the input after a postback. Could you try using actual TextBox controls?

Categories