I've tried and tried but just cannot get a hold of this so let me explain my problem.I have a survey website using xml survey files. On one page I have a category menu which passes relative surveys filename to another page in the redirect as a query string.
~/websurvey.aspx?Survey=gamesurvey.xml
so the name of the survey file is gamesurvey.xml. On another page I have the following to read the filename into a string.
string c = Request.QueryString["Survey"];
now here lies my problem. The control that I have to pass the filename to does not recognise any attempts I make at trying to "dereference" the string. Here is the part in question.
<sstchur:WebSurvey id = "ws"
SurveyFile = "gamesurvey.xml"
AnswersFile = "answers.xml"
runat = "server"/>
</form>
Above where you see gamesurvey.xml thats where I need to pass the string. Here it is hardcoded.This is a problem because I want to be able to call any survey by way of query string without having to make new pages for each of them.
If I put things like
""+c+"" or .toString() or SurveyFile = c
it tells me the server tag is not well formed.
To sum up my problem I need to pass a filepath directly from page to page. By the way, when I put SurveyFile = c I get a pageload error saying the file c cannot be found, i.e. this control will only take a filename not a variable containing it.
Sorry if this is hard to understand but my head is just melted with it now I had to ask.
Any help would be appreciated.
The control im using is the WebSurvey control 4GuysFromRolla and yes I have checked all the documentation and the few forum posts related to it.
And what prevents you from setting that control property in your code-behind?
If you've your "page.aspx.cs", just do that in the Page.Init Page.Load event and you'll be fine!
Maybe I'm wrong and you can't use code-behind or something like that.
i am giving u few options
use
SurveyFile= <% c %>
or since you are not passing the full file path so ur file is not found. give it like ~//root//directory//filename.extension
or may be
u can find some methods to set that parameter using the code behind page.
do tick my answer correct if found useful
Related
We have a large site and there are a few instances where a single basic content item is shared and re-used on 5 to 12 pages. The site has over 10 editors and at least half of those are infrequent, so not remembering that these items are shared is a repeated problem. They keep changing the content on one page adding specifics that then look weird, broken, or very out of place on one or more other pages.
What I would like to do is add some code to the View that detects the item is shared and then add an indicator. Obviously this would be perfect:
if(Content.IsSharedItem) {
// add a nice blue, round 2sxc style button with a
<i class="fas fa-share-alt"></i>
}
I poked around the API, but beyond writing some LINQ (that could be processor intensive), I haven't spotted any way to implement anything like .IsSharedItem
Any ideas or suggestions? Is there something built-in that I might not be aware of or named in a way that I didn't think to search? Any help would be greatly appreciated. Thank you in advance.
DNN 9.03.02, 2sxc 10.9.1, Content App 3.03
There actually is :).
Let's assume that shared means "it's been manually assigned to a module". In this case there is another Entity which references the one you are interested in.
Basically if you ask any item for .Parents("2SexyContent-ContentGroup") you should get all Content-Groups referencing it.
Just remember that some may be deleted etc. so it's not 100% reliable or would need more work.
I couldn't see how to get from .Parents() to TabID, so I realized, we are executing in the module, so simply doing Dnn.Module.ModuleSettings["ToSIC_SexyContent_ContentGroupGuid"] gives you what you need. Then DNN has no API way to reverse a ModuleSetting.SettingValue, e.g. there is no GetModulesByModuleSettingValue() type thing. So SQL started to make sense and I did this instead...
I would be really interested if anyone has ways to improve this. Better query? A way to do it without SQL? Refactor or simplify some things? For example, adding the TabName was an afterthought and probably should have been done in SQL.
Add this to any Content item View, wrap it in an if(Edit.Enabled) or something so only editors/admins see it.
#if(Edit.Enabled) {
#RenderPage("_Shared__ContentGroup-Info.cshtml")
}
Save this to a filename _Shared__ContentGroup-Tabs.cshtml (above)
#using System.Data
#using DotNetNuke.Data
#using DotNetNuke.Entities.Tabs
#*
This sub template is intended to
a) reveal whether or not the Content item is shared and
b) show links to those pages
Reminder the .Parents("2SexyContent-ContentGroup")..EntityGuid is what is stored in
Dnn.Module.ModuleSettings["ToSIC_SexyContent_ContentGroupGuid"]
*#
#{
string sql = #"
SELECT DISTINCT TabID
FROM TabModules
INNER JOIN ModuleSettings ON TabModules.ModuleID = ModuleSettings.ModuleID
WHERE ModuleSettings.SettingValue = '{0}'";
sql = string.Format(sql, Dnn.Module.ModuleSettings["ToSIC_SexyContent_ContentGroupGuid"]);
IList<int> tabs;
using (IDataContext db = DataContext.Instance()) {
tabs = db.ExecuteQuery<int>(CommandType.Text, sql).ToList();
}
}
<pre>
This Content item is shared to #(tabs.Count - 1) other page(s)
#foreach(int tabId in tabs
.Where(t => t != Dnn.Tab.TabID)
) {
#TabController.Instance.GetTab(tabId, Dnn.Portal.PortalId).TabName
}
</pre>
Example output:
So then, since we already have Bootstrap 4 and Fancybox on the pages, I was able to turn the experiment in to a working UI with about 5 more mins of playing around:
I'm trying to create this global method that click on this link called "Categories". The ID (t_166) is dynamic, Xpath (//*[#id="t_166"]) and "copy selector" (#t_166) use the id number also so they won't work.
So, I'm left with the html:
I figured class would be a good candidate. So... to start:
var categorymenu = driver.instance.findelement(by.classname("fontMediumBigColorGrey navigatorLinkClicked z-label")
And then I want it to find the category one and click on it, something like:
categorymenu.getattribute(category).click();
Two problems.
Problem 1: The link's class changes depending if you've visited it previously, or the "linkclicked" part in it. It becomes "fontMediumBigColorGrey z-label" if you haven't been on it. Question: it won't be able to find categories if the class is different. How would I handle this?
Problem 2: There are many other links (like users) that use the same classes, so shouldn't I be using findelements and then isolate it by an attribute (category is this case) But findelements doesn't seem to be able to use getattribute (because there are many of them) so how do I cover that part?
Thanks!
You can use search by XPath to find your element:
var categorymenu = driver.instance.findelement(by.xpath("//span[text()='Categories']")
In code above you search for span element with "Categories" as its text value
Also you can try to ignore dynamically changing part of id attribute in following way:
var categorymenu = driver.instance.findelement(by.xpath("//div[starts-with(#id, 't_')][substring-after(#id, '-')='cave']/span")
Above code should search for span that is child of div with id="t_XXXX-cave" where XXXX is ignored part
Note You should also be aware that you will not be able to complete categorymenu.getattribute(category).click(); as categorymenu.getattribute(category) (actually categorymenu.GetAttribute(category)) returns just a string value
In case you want to see if the span has the fontMediumBigColorGrey class:
var categorymenu = driver.instance.findelement(by.xpath("//span[contains(#class, 'fontMediumBigColorGrey')]")
In case you want to see if the text is equal to "Categories":
var categorymenu = driver.instance.findelement(by.xpath("//span[text()='Categories']")
A trick that I sometimes use, and could be useful for you too - if you're using Chrome, open the console and edit the HTML in such a way that you delete the "id" tag. Then, right click and choose 'Copy > Copy XPath'. This will copy the XPath but neglect the ID (because you can't use it since it's dynamic).
I'm trying to get a list of IwebElements that contain the attribute aria-required. Reason why I'm trying to get this list, is so that i can check if all required fields are necessary for the user to fill out, before he can continue to the next page.
So far after 2 days of searching I'm still convinced that it shouldn't be that hard. I'm using the expression:
".//*[#aria-required='true']"
From my research that would mean that it will search for ALL the elements starting from the root of my webdriver.
[TestMethod]
public void CreateProjectWithoutRequiredFields()
{
GoToProjectPage();
tracking = CM.GoToNewlyCreatedFrameAfterClickButton("ftbNew", tracking, theDriver);
CM.Wait(2000);
bool succesSave = false;
CM.LogToFile("Create project whitout required fields", tracking);
foreach (IWebElement e in theDriver.FindElements(By.XPath(".//*[#aria-required='true']")))
{
FillDataInNewProjectPage();
e.Clear();
CM.GetDynamicElementById("btnSave", theDriver).Click();
try
{
CM.GetDynamicElementById("titel", theDriver).Click();
}
catch (Exception)
{
succesSave = true;
NUnit.Framework.Assert.IsFalse(succesSave, "The page is saved with succes, without entering text in the following required fields : " + e.GetAttribute("id").ToString());
}
CM.Wait(1000);
}
}
I will try to explain what i did here:
First i went to a overview page with all my existing projects. On this page i clicked the ftbNew button to create a new project. The driver is automatically switch to the correct frame (i now the right frame is selected because i used this line on other page's.)
then the line
foreach (IWebElement e in theDriver.FindElements(By.XPath(".//*[#aria-required='true']")))
{
should normaly find a the elements in my driver with an attribute "aria-required='true'"
Then it would fill in the page with data, clear the first element that is found from its data en try to save it.
if the element titel is found on the page, than we are still on the same page en the save action wasn't successful ( <- so this is good)
so next we again overwrite every field on the page and clear this time the second element that is found.
en so on...
What I'm guessing, that xpath has difficulty finding the 'old' aria-required attribute... When i try to validate my expression using firebug and other xpath checkers, the aria-required attribute isn't always present. Sometimes it finds the input field sometimes it doesn't.
source code page
As you can see in the firebug console not all attributes are loaded, account-manager has a aria-required attribute, but project leader doesn't. If i inspect the element again, but this time click project leader. The attribute will be loaded. Very strange....
Extra info: I am using frame's and i know a lot can go wrong if you are situated in the wrong frame, but i am sure that he is looking in the correct frame. Especially because i can't find the elements using firebug with the above expression. If i change my expression to .//input, it will find the elements but also selects input fields that aren't required.
In advance i want to thank everybody that want to look into my problem :)
Adriaan
Based on your description of the behavior on the page, you cannot rely on the aria-required attribute to indicate a required field. I think that you should go back to the developers of the site to ask them to give you a reliable handle. It may be as simple as looking for the "*" as the last character of the label associated with the input field, but that's kind of annoying to have to deal with.
As an aside, you should consider catching a more specific exception for your success case. Right now, if ANY exception happens, you'll declare success, but that may not be what you really want to do.
I stucked at a condition , where i need to share values between the pages. I want to share value from Codebehind via little or no javascript. I already have a question here on SO , but using JS. Still did'nt got any result so another approach i am asking.
So I want to know can i pass any .net object in query string. SO that i can unbox it on other end conveniently.
Update
Or is there any JavaScript approach, by passing it to windows modal dialog. or something like that.
What I am doing
What i was doing is that on my parent page load. I am extracting the properties from my class that has values fetched from db. and put it in a Session["mySession"]. Some thing like this.
Session["mySession"] = myClass.myStatus which is List<int>;
Now on one my event that checkbox click event from client side, i am opening a popup. and on its page load, extracting the list and filling the checkbox list on the child page.
Now from here user can modify its selection and close this page. Close is done via a button called save , on which i am iterating through the checked items and again sending it in Session["mySession"].
But the problem is here , when ever i again click on radio button to view the updated values , it displays the previous one. That is , If my total count of list is 3 from the db, and after modification it is 1. After reopening it still displays 3 instead of 1.
Yes, you could but you would have to serialize that value so that it could be encoded as a string. I think a much better approach would be to put the object in session rather than on the URL.
I would so something like this.
var stringNumbers = intNumbers.Select(i => i.ToString()).ToArray();
var qsValue = string.Join(",", stringNumbers);
Request.Redirect("Page.aspx?numbers=" + sqValue);
Keep in mind that if there are too many numbers the query string is not the best option. Also remember that anyone can see the query string so if this data needs to be secure do not use the query string. Keep in mind the suggestions of other posters.
Note
If you are using .NET 4 you can simplify the above code:
var qsValue = string.Join(",", intNumbers);
Make the object serializable and store it in an out-of-process session.
All pages on your web application will then be able to access the object.
you could serialize it and make it printable but you shouldn't
really, you shouldn't
The specification does not dictate a minimum or maximum URL length, but implementation varies by browser and version. For example, Internet Explorer does not support URLs that have more than 2083 characters.[6][7] There is no limit on the number of parameters in a URL; only the raw (as opposed to URL encoded) character length of the URL matters. Web servers may also impose limits on the length of the query string, depending on how the URL and query string is stored. If the URL is too long, the web server fails with the 414 Request-URI Too Long HTTP status code.
I would probably use a cookie to store the object.
i have placed a SqlDataSource component on my aspx page but while configuring the SqlDataSource in the "Test Query" Step I am passing the following parameters :
But when i click ok it returns following error:
This error occurs when i pass the string :
INFO, WARN, ERROR,
I have tried a lot of combinations but nothing works. It works only if i pass one of the three words in single quotes like this :
'ERROR'
Infact the INFO WARN and ERROR are the various levels available in the table. Each record can have only one level and in the sql query i am using IN("-----") to match the criteria, hope you understand.
Any idea to pass the string with comas between them will be highly appreciated.
After you create the page with the dialogue helpers, just switch to code view of your html and change them by hand on the created code...
I have resolved the problem by passing each level in single quotes without , after the last level as shown in the image below:
Anyway thanks for your help Aristos!