Cocoa getting input data from DOMDocument - c#

I'm trying to get data from the DOM from a document loaded into a Cocoa WebView control but it seems like the element's value is empty. I'm using MonoMac. The code I'm using (C#) is below:
var document = WebBrowser.MainFrameDocument;
if (document != null)
{
// GetAllChildren is a recursive extension function that iterates through a DomNode's
// ChildNodes property and returns a list of all of them
var textareaElements = document.GetAllChildren().OfType<DomHtmlElement>().Where(node => node.Name.Equals("TEXTAREA"));
foreach (var textarea in textareaElements)
{
var value = textarea.Value; // this is always ""
}
}
Do I need to do something to make sure the DOM reference I have to has the data entered into the webpage?

I rarely have to work with DOM but it seems to be the returned node is of type Element and the nodeValue will return a string only for a Text type.
From an Element you can try the TextContent, that does return the expected value for the bug report you mentioned.
Or you can access the Text node (it will be textarea.FirstChild.Value in your case) and that should also return the value you expect.
UPDATE
The original test case from the bug report did not show the real issue. A newer test case was provided and a fix is now available (on github monomac repo).

This appears to be a bug in the MonoMac implementation: https://bugzilla.xamarin.com/show_bug.cgi?id=7754
UPDATE: There is an active pull request that fixes this issue: https://github.com/mono/monomac/pull/109

Related

Umbraco: Get Grid content in search results?

I have a simple Examine search like so;
var results = Umbraco.Search(Request.QueryString["query"], true, "MySearcher");
foreach (var result in results)
{
<h2>#result.Name</h2>
<p>Content from 'contentgrid'?</p>
}
My question is, how do I get a snippet of text from the Grid? Propertyname is contentgrid.
Viewing the index, I can see there is a property named contentgrid containing the text, stripped from formatting etc.
Hi I wrote some code to allow you to do a more advanced search in umbraco.
This article gives you that code.
http://www.codeshare.co.uk/blog/how-to-search-by-document-type-and-property-in-umbraco/
I use it for the search on my website. The word mismatched only appears in the content grid for one article of my site. The below search url proves that it works.
http://www.codeshare.co.uk/search/?query=mismatched
Kind regards
Paul
I think there are two approaches you could take.
One is to add a custom field in the Examine index and then using the GatheringNodeData event, index the text that you want to display. That way you will be able to access it from the SearchResult object (#result.Fields["customFieldName"]). The GatheringNodeData event handler will have to parse the grid data to extract the text snippet you want and then add it to the Examine document (e.Fields["content"] = textSnippet).
The other approach would be to get the text snippet from the node when displaying the results.
var helper = new UmbracoHelper(UmbracoContext.Current);
foreach (var result in results)
{
var node = helper.TypedContent(result.Id);
var gridData = node.GetPropertyValue("contentgrid");
// some code for extracting the text snippet from the grid data
}
Note in both techniques, you need to figure out how to extract the text snippet you want from the grid data. You could use Skybrud.Umbraco.GridData or just parse the JSON yourself (using JSON.NET). I think the post #Harvey mentioned in a comment yesterday would be helpful for this (and more details on handling the GatheringNodeData event).

How to get a list of elements with Watin (c#) and change values?

i want use watin to get list of elements in a webpage and change all the values
for example i want find all textboxes with "test" ID
and change their values
this is my code. but it only change one element, not all ( in my code i looked for elements via thir name )
IE ie = new IE("http://sample.net/");
ie.TableRow(Find.ByText(t => t.Contains("sample text"))).TextField(Find.ByName("second text")).TypeText("write this string");
ie.WaitForComplete();
in this code i find a text in a table, then i find text box (second text) , then it write "write this string"
but it i want to do this for all the similar elements
i tried with foreach but failed
anyone knows the right code?
I can see that you have targeted to a TableRow and used TextField which would be only a textfiled. You should be targeting parent and try to get all the text fields with your criteria.
I have tried with below code and worked for me. If you still unable to figure out the issue, you post the error/html source code.
IE ie = new IE("https://accounts.google.com/SignUp?service=mail&continue=https%3A%2F%2Fmail.google.com%2Fmail%2F&ltmpl=default");
ie.WaitForComplete();
foreach (var txtEle in ie.Form(Find.ById("createaccount")).TextFields)
{
if (!string.IsNullOrEmpty(txtEle.Id))
{
if (txtEle.Id.Contains("Name"))
{
txtEle.TypeText("write this string");
}
}
}
ie.WaitForComplete();

Create NestedContent Items In SurfaceController

I have two document types:
FormSubmission
FormField
The Form document type has a property named Fields which is a Nested Content data type that contains a list of FormField document types. I am trying to programmatically (in a SurfaceController) create a FormField and add it to the Fields property of the Form document type.
Here is the code I am trying to use to do this:
var newFormFields = new List<Umbraco.Core.Models.IContent>();
int i = 0;
foreach (var formField in model.Fields)
{
string fieldName = string.Format("Field {0}", i);
var newFormField = contentService.CreateContent(fieldName, newFormSubmission.Id, "formFieldSubmission", formNode.CreatorId);
newFormField.SetValue("fieldName", formField.Name);
newFormField.SetValue("fieldType", formField.Type);
newFormField.SetValue("manditory", formField.Manditory);
newFormField.SetValue("fieldValue", formField.Value);
newFormFields.Add(newFormField);
++i;
}
newFormSubmission.SetValue("fields", newFormFields);
var status = contentService.SaveAndPublishWithStatus(newFormSubmission, formNode.CreatorId, raiseEvents: false);
On the newFormSubmission.SetValue("fields", newFormFields); line it throws this exception:
The best overloaded method match for 'Umbraco.Core.Models.ContentBase.SetPropertyValue(string, string)' has some invalid arguments
Anyone have any ideas how to store a list of DocumentTypes in the Nested Content data type?
PS: I am using Umbraco version 7.4.0 assembly: 1.0.5885.31226
UPDATE:
Lee Kelleher pointed me in the right direction towards developing my own solution in this post on the umbraco forms. I hope to have time after this project to polish up my solution and submit a pull request to the project.
I basically ended up creating some extension methods that take an IEnumerable<IContent> and return a JSON representation of the objects for the NestedContent plugin.
This gist might help you:
robertjf/NestedContentCreator.cs
There's an example in the second file further down. It was written last year and may require some tweaking; but it should give you a good start.
It seems that the second argument of the SetPropertyValue method expects a string and you are passing a List<Umbraco.Core.Models.IContent>

Umbraco: Unable to get RelatedLinks property value in code-behind

I have a RelatedLinks property in one of my pages that I need to get the links/PageIds out from in the code behind of my macro-user control.
I can get the property like this
var current = Node.GetCurrent();
Response.Write("Output: " + current.GetProperty("RelatedLinks").Value);
But the output is empty. When I debug I can see that the Value includes some list content (like tags and such) some somehow nothing is printed.
My question is how I can get the value from this property into something like a collection of hyperlink objects.
I'm new to Umbraco and I's possible that I'm missing something essential here. Getting the content of other property types (like the Content Picker) works fine.
Thanks!
You can use this simple solution in Umbraco 7.+
Model.Content.GetPropertyValue<Umbraco.Web.Models.RelatedLinks>("relatedArticles");
this simply convert data to static type that is easy to use.
What data type is your related links set to, assuming its a content picker where you are getting the id of the related page you could first create a node form your current page's id then try and get the value from that node e.g.
var current = Node.GetCurrent();
var currentPage = Model.NodeById(current.Id);
var relatedLinks = currentPage.RelatedLinks;
or
var relatedLinks = GetProperty("RelatedLinks").Value;
when you debug you should be able to see all the properties of currentpage and check your alias as well to make sure its right (generally aliases dont start with a capital by default).
Try this umbraco.NodeFactory.Node.GetCurrent().GetProperty("RelatedLinks")
Solved it like this:
Document doc = new Document(Node.GetCurrent().Id);
umbraco.cms.businesslogic.property.Property relatedLinks = doc.getProperty("RelatedLinks");
XmlNode relatedLinksAsXml = relatedLinks.ToXml(new XmlDocument());
However it says that the Document class is obsolete and wants me to use Umbraco.Core.Models.Content instead. But this is MVC right? I'm trying to use webforms. Tried using the Node class as described in this thread but the Property object I got returned was of the wrong type and couldn't be converted to XML.

How to get object in C# when it is dynamically created by javascript

I created several input text in Javascript in my .aspx
for (var i = 0; i < listbox.options.length; i++) {
var text = listbox.options[i].value;
var element = document.createElement("input");
//Assign different attributes to the element.
element.setAttribute("type", "text");
element.setAttribute("value", text);
element.setAttribute("id", "TMruleItem");
element.setAttribute("style", "width:480px; margin-top:10px");
element.setAttribute("disabled", "disabled");
element.setAttribute("runat","server");
var foo = document.getElementById("Panel_TM");
foo.appendChild(element);
}
However, when I try to get the text of this object in C#(code behind the .aspx), it seems impossible. Can anybody help with this? Thanks a lot!
The js runs client side AFTER the C# (server side) has rendered the page.
You cannot do what you want because you have fundamentally flawed model of how these technologies interact.
Having said that; you could implement a web service or ajax framework to pass the text value to the server.
I'm not exactly sure how you will add this into the C# side of things (which live on the server), because this element is only being added to the clientside (even if you add an attribute runat="server"), because the page that was generated has been sent.
However, if you need to be able to add elements dynamically, you could always pass some information using an ajax call (etc) that is stored somewhere (a database) that is then read to re-create the html element next time the page is generated...
End result though is that for the C# to be able to access the element, it must exist at some point on the server. If instead of accessing the element, you just want to access the value, provided the form is posted (ajax or regular) the value will be part of the Request variables:
string value = Request.Params["TMruleItem"];
Add the following to your javascript code:
element.setAttribute("name", "TMruleItem");
and entered values will be available on the server side:
string value = Request.Form["TMruleItem"];
I think you'd need to add the element to the form and when you post back to the server you can pull the value out using Request.Form

Categories