Postback not working on mouse click in Safari - c#

So I have a dropdown context box, which I use to select which item I am going to be working with.
Now everything seems to be working on all browsers except Safari. I have a type function that works fine in safari if you focus on the box and type the name in and hit enter. However my issue is with the mouse click. If I select an item from the dropdown and click it, the postback doesn't work until I hit enter on the keyboard.
Here is my .ascx.cs file
...
if (cboContext.Visible)
{
string postBackFunction = "function contextPostback() {\n"
+ "var newValue = document.getElementById(\"" + cboContext.ClientID + "\").value;\n"
+ "if (newValue != " + cboContext.SelectedValue + ") " + Page.ClientScript.GetPostBackEventReference(cboContext, "") + ";\n}";
Page.ClientScript.RegisterClientScriptBlock(typeof(string), "contextPostback", postBackFunction, true);
if (Request.UserAgent.ToLower().IndexOf("chrome") > -1)
{
cboContext.Attributes.Add("onkeypress", "if (typeAhead(event,'" + cboContext.ClientID + "') == 1) contextPostback();");
cboContext.Attributes.Add("onclick", "contextPostback();");
}
else if (Request.UserAgent.ToLower().IndexOf("safari") > -1)
{
cboContext.Attributes.Add("onclick", "contextPostback();");
cboContext.Attributes.Add("onkeypress", "if (typeAhead(event,'" + cboContext.ClientID + "') == 1) contextPostback();");
cboContext.Attributes.Add("onkeydown", "if (typeAhead(event,'" + cboContext.ClientID + "') == 1) contextPostback();");
cboContext.Attributes.Add("onkeyup", "if (typeAhead(event,'" + cboContext.ClientID + "') == 1) contextPostback();");
}
else
{
cboContext.Attributes.Add("onkeydown", "if (typeAhead(event,'" + cboContext.ClientID + "') == 1) contextPostback();");
cboContext.Attributes.Add("onclick", "contextPostback();");
}
}
Here is the typeAhead() function
function typeAhead(e, nextFocus) {
//don't trap Ctrl+keys
if ((window.event && !window.event.ctrlKey) || (e && !e.ctrlKey)) {
// timer for current event
var now = new Date();
....
if (inputBuffer.accumString == "" || now - inputBuffer.last < inputBuffer.delay) {
//check for browsers
var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
var is_safari = navigator.userAgent.toLowerCase().indexOf('safari') > -1;
// make shortcut event object reference
var evt = e || window.event;
// get reference to the select element
var selectElem = evt.target || evt.srcElement;
// get typed character ASCII value
var charCode = evt.keyCode || evt.which;
// get the actual character, converted to uppercase
var newChar = "";
// get reference to the actual form selection list
// added cross browser fix to enable the context switcher to work properly
if (is_chrome) {
var selection = document.getElementById("ctl00_ContextSwitch1_cboContext").selectedIndex;
}
else {
var selection = document.getElementById(nextFocus);
}
....
Now I have a section in the typeAhead for the chrome browser, but everything I try for safari doesn't seem to allow me to use the mouse click to select an item.
Any help would be appreciated.

simple fix. safari recognizes onchange so once I added that, it worked fine.

Related

Saving objects with FindObjectsOfTypeAll()

I have a save-Method to save informations about every block with one of five specific tags, like position, health, rotation etc.
I first want to get all objects (even inactive ones), so i use the FindObjectsOfTypeAll()-Method.
Then i go with a foreach loop through all of the objects that have been found, and check if they have the right tag and if they do, i save them.
This is the code i use:
GameObject[] allObjects = Resources.FindObjectsOfTypeAll(typeof (GameObject)) as GameObject[];
using (StreamWriter write = new StreamWriter(dir + "blocksSave.dat"))
{
Debug.Log(allObjects.Length);
foreach (GameObject block in allObjects)
{
bool isActive = block.activeSelf;
block.SetActive(true);
if (block.tag == "WoodBlock" || block.tag == "WoodSteps" || block.tag == "WoodRamp" || block.tag == "GlasBlock" || block.tag == "WoodDoor")
{
// SAVE
write.WriteLine(block.tag + "," + block.transform.position.x + "," + block.transform.position.y + "," + block.transform.position.z + "," + block.GetComponent<BlockControl>().GetHealth().x + "," + block.GetComponent<BlockControl>().GetHealth().y + "," + block.transform.rotation.x + "," + block.transform.rotation.y + "," + block.transform.rotation.z);
}
block.SetActive(isActive);
}
write.Close();
}
I debugged this and the line if (block.tag == "WoodBlock" || ...) works fine.
The problem is the next line:
write.WriteLine(...);
here i get a nullReferenceException, where it tells me:
NullReferenceException: Object reference not set to an instance of an
object
And i can't figure out why?!
The issue is very probably that
block.GetComponent<BlockControl>()
returns null for one of your found GameObjects since it simply does not have that component.
Instead you could use
Resources.FindObjectsOfTypeAll<BlockCo troll>();
to be sure you only have all the components of type BlockControl in a separate list.
Than you can use a List to easier filter the objects for the tag instead of those || conditions
var searchedTags = new List<string>()
{
"WoodBlock",
"WoodSteps",
"WoodRamp",
"GlasBlock",
"WoodDoor"
};
if (searchedTags.Contains(block.gameObject.tag))
{
....
}
or even esier use Linq to only get the objects you are interested in:
var objectsOfInterest = allObjects.Where(obj => searchedTags.Contains(obj.gameObject.tag)).ToList();
I would also only use the StreamWriter for actually writing and do nothing else within that using block.
And note that if you are using a StreamWriter inside of a using block you don't have to use write.Close() since it is disposed automatically after the using block finishes.
So in complete I would use something like
var searchedTags = new List<string>()
{
"WoodBlock",
"WoodSteps",
"WoodRamp",
"GlasBlock",
"WoodDoor"
};
// This list is used to get all GameObject
// keep track which where active and activate all
var allObjects = Resources.FindObjectsOfTypeAll<GameObject>();
// Here we get all BlockController components
var allBlockObjects = Resources.FindObjectsOfTypeAll<BlockController>();
// finally we only get BlockControllers with the tags we want
var objectsOfInterest = allBlockObjects.Where(obj => searchedTags.Contains(obj.gameObject.tag)).ToList();
Debug.Log("objects total: " + allObjects.Length);
Debug.Log("block objects: " + allBlockObjects.Length);
Debug.Log("objects of interest: " + objectsOfInterest.Length);
// Step 1 keep track which GameObjects where active and activate all
var objectWasNotActive = new List<GameObject>();
foreach (var obj in allObjects)
{
if(!obj.activeSelf)
{
// keep track which objects where not active
objectWasNotActive.Add(obj);
}
// Set all to true
obj.SetActive(true);
}
// Step 2 save your BlockControllers with searched tags
using (StreamWriter write = new StreamWriter(dir + "blocksSave.dat"))
{
foreach (var block in objectsOfInterest)
{
// Here you already have components of type BlockController
// so you don't need to get them
// But GetHealth might also return null so maybe you want to check that too
// It is up to you whether you want to skip or fill it with default values in such case
var health = block.GetHealth();
if(health == null)
{
//option 1 skip
continue;
// OR option 2 default e.g.
// Assuming it is Vector2
health = Vector2.zero;
}
// SAVE
write.WriteLine(
block.gameObject.tag + ","
+ block.transform.position.x + ","
+ block.transform.position.y + ","
+ block.transform.position.z + ","
+ health.x + ","
+ health.y + ","
+ block.transform.rotation.x + ","
+ block.transform.rotation.y + ","
+ block.transform.rotation.z
);
}
}
// Step 3 disable those GameObjects again that where not active before
foreach(var obj in objectWasNotActive)
{
obj.SetActive(false);
}
Now it's really hard to debug this without seeing the code, but try checking this first.
Check if write is being properly initialized without errors, sometimes it fails silently.
Are you sure that all of your objects with those tags have the component BlockControl on them ?
try updating your code to this just to check where exactly is it failing
if (block.tag == "WoodBlock" || block.tag == "WoodSteps" || block.tag == "WoodRamp" || block.tag == "GlasBlock" || block.tag == "WoodDoor")
{
Debug.Log(block.name);
Debug.Log(block.GetComponent<BlockControl>());
Debug.Log(block.GetComponent<BlockControl>().GetHealth());
// SAVE
write.WriteLine(block.tag + "," + block.transform.position.x + "," + block.transform.position.y + "," + block.transform.position.z + "," + block.GetComponent<BlockControl>().GetHealth().x + "," + block.GetComponent<BlockControl>().GetHealth().y + "," + block.transform.rotation.x + "," + block.transform.rotation.y + "," + block.transform.rotation.z);
}
This way you can find out which block is causing the issue and if the problem is with the component or the GetHealth() function.

Show a message-box when the database is empty

thanks for viewing my question. Basically, when the user clicks on a button, it will either say one of the following in a message box based on what the database has: Your holiday has been authorised, your holiday has been declined or your holiday request has been sent.
I want it so that when the user clicks on the button and there isn't any data in the database because the user hasn't sent a holiday request, to receive a message box saying that they haven't booked an holiday.
Here's my code:
private void button2_Click_1(object sender, EventArgs e)
{
System.Windows.Forms.Form f = System.Windows.Forms.Application.OpenForms["Login"];
SundownDatabaseEntities6 db = new SundownDatabaseEntities6();
int id = Convert.ToInt32(((Login)f).idTb.Text);
var getrecords = db.Holidays.Where(a => a.Id == id).ToList();
foreach (var record in getrecords)
{
if (record.YesOrNo == "yes")
{
MessageBox.Show("The manager has accepted your holiday (From " + record.Datefrom + " - " + record.Dateto + ").");
}
else if (record.YesOrNo == "no")
{
MessageBox.Show("The manager has declined your holiday request (" + record.Datefrom + " - " + record.Dateto + ").");
}
else if (record.YesOrNo == null)
{
MessageBox.Show("Your holiday request (" + record.Datefrom + " - " + record.Dateto + ") has been sent.\nWaiting for manager to authorise it...");
}
else if (record != null)
{
MessageBox.Show("You have not booked an holiday.");
}
}
}
Problem is on the last bit of the code, the 'else if(record != null)' doesn't check if the database is empty. Any suggestions? Thanks!
You should check getrecords.Count()
var getrecords = db.Holidays.Where(a => a.Id == id).ToList();
if (getrecords.Count() == 0)
{
// ... here your logic
}
Or
if (!db.Holidays.Any ())
Because it won't go to foreach if getrecords is empty.

IHTMLDocument Events are not working with the COM BrowserControl

I'm trying to automate a website, and I have the following piece of code to change the value of a dropdown (select):
private bool ChangeElementSelection(mshtml.IHTMLDocument3 document, string id, string value)
{
var el = document.getElementById(id);
if (el != null)
{
log.Write("Setting HTML element " + id + " value to " + value + " (by ID)");
el.setAttribute("value", value);
var el3 = (el as IHTMLElement3);
el3.FireEvent("onchange");
return true;
}
log.Write("Could not find HTML element " + id + " (by ID)");
return false;
}
The website I am visiting uses JQuery to catch the "change" event for the select element. It does not expect any parameters. Yet the script is not triggered. Why ?

How to set sessions of the page before sending it through a web service?

I have the following case but i don't know how to do it .
I have a page say [page1.aspx] this page have a button in the event click of this button i call a method in web service , this method need a url as a param , every thing goes okay and the receiver ,receive the url ,but when clicks on that link ,it redirects to the login page instead of the sent page !! How to open the sent page which has sessions in a secure manner ?
protected void SendNotification(int StateSerial)
{
DataTable dt = Utilities.GetStateUsers(StateSerial, taskCode);
if (dt != null && dt.Rows.Count > 0)
{
string message = Session["TransDes"].ToString().Trim();
string sender = Session["send"].ToString().Trim();
string sys_code = "SM" + "|" + taskCode.ToString();
string sys_name = Task.GetTask(taskCode).Rows[0]["task_name"].ToString();
for (int i = 0; i < dt.Rows.Count; i++)
{
string emp_num = dt.Rows[i][0].ToString();
string serial = taskCode.ToString() + "|" + obj.TransSerial + "|" + obj.TransYear;
}
string URL_inbox = "https://..../Page1.aspx?TCode=" + taskCode + "&TransSerial=" + obj.TransSerial + "&TransYear=" + obj.TransYear + "&mainCode=" + obj.MainCode + "&year=" + obj.Year + "&MCode=" + obj.MainCode + "&DYear=" + obj.Year + "&AR=1";
Service1 noti = new Service1();
string res = noti.sendNotification(emp_num, message, URL_inbox, sender, serial, sys_code, sys_name);
}
}
}
Now the user receive the URL_inbox but when clicks on it it redirects to the login page instead
because the following code is in the page load of Page1.aspx
if (Session["emp_num"] != null && !string.IsNullOrEmpty(Session["emp_num"].ToString()))
{
emp_numb = int.Parse(Session["emp_num"].ToString());
}
else
{
Response.Redirect("https://..../LoginPage.aspx");
}
How to handle this problem in secure manner ?

Weird issue in c# related to DataSet

I'm currently working on a program that converts japanese characters to english characters and the other way around.
It's not working much though, For the last few days I've been trying everything to try and get it to work, it's probably some small dumb problem but I just can't find it. I'm pretty new to all this so any help is appreciated.
Now the problem is that it only wants to convert Romaji characters, however if change some code, more specifically if I change the following from "if" to else if, then it converts hiragana and katakana but NOT romaji..
string fromtype = "";
// Determines what type the character is currently
// && fromtype == "" added to avoid weird unexplainable errors...
if (CharacterTable.Select("Romaji = '" + character + "'") != null && fromtype == "")
{
fromtype = "Romaji";
}
else if (CharacterTable.Select("Hiragana = '" + character + "'") != null && fromtype == "")
{
fromtype = "Hiragana";
}
else if (CharacterTable.Select("Katakana = '" + character + "'") != null && fromtype == "")
{
fromtype = "Katakana";
}
I've even tried removing this function that tries to automatically find what type the character is and do it with radiobuttons so that the user has to select it, but somehow it seems to do pretty much the same thing... So I'm totally confused at this point, any help is very much welcome.
Here is the full code:
public string CheckCharacter(string character, int RequestedCharType)
{
// RequestedCharType
// 1 = Romaji
// 2 = Hiragana
// 3 = Katakana
//-- Instantiate the data set and table
DataSet CharacterDatabase = new DataSet();
DataTable CharacterTable = CharacterDatabase.Tables.Add();
//-- Add columns to the data table
CharacterTable.Columns.Add("Romaji", typeof(string));
CharacterTable.Columns.Add("Hiragana", typeof(string));
CharacterTable.Columns.Add("Katakana", typeof(string));
//-- Add rows to the data table
CharacterTable.Rows.Add("a", "あ", "ア");
CharacterTable.Rows.Add("i", "い", "イ");
// Sets fromtype to the type the character(s) currently is/are
string fromtype = "";
// Determines what type the character is currently
// && fromtype == "" added to avoid weird unexplainable errors...
if (CharacterTable.Select("Romaji = '" + character + "'") != null && fromtype == "")
{
fromtype = "Romaji";
}
else if (CharacterTable.Select("Hiragana = '" + character + "'") != null && fromtype == "")
{
fromtype = "Hiragana";
}
else if (CharacterTable.Select("Katakana = '" + character + "'") != null && fromtype == "")
{
fromtype = "Katakana";
}
// generates a new variable to store the return in
DataRow[] filteredRows = CharacterTable.Select(fromtype + " = '" + character + "'");
// Return the converted character in the requested type
foreach (DataRow row in filteredRows)
{
if (RequestedCharType == 1)
{
return row["Romaji"].ToString();
}
if (RequestedCharType == 2)
{
return row["Hiragana"].ToString();
}
if (RequestedCharType == 3)
{
return row["Katakana"].ToString();
}
}
// if it couldn't find the character, return the original character
return character;
}
Your problem is in your misunderstanding of how Select works. Select does not return null when there are no matches so your first if is always true. Instead you need to check whether there were any results which you can do with Enumerable.Any() (add using System.Linq):
if (CharacterTable.Select("Romaji = '" + character + "'").Any())
{
fromtype = "Romaji";
}
else ...
Alternatively you can check the array length:
if (CharacterTable.Select("Romaji = '" + character + "'").Length > 0)
{
fromtype = "Romaji";
}
else ...
I'm not sure what the fromType == "" bit is all about this is surely not needed.
Considering creating an enum type for your char types.
This method can be made static.
Consider using a switch statement instead of if (RequestedCharType == 1)
&c.

Categories

Resources