WebSharper : How to create a menu with jQueryUI - jquery-ui

I would like to use JQueryUI provide by WebSharper in order to create a menu.
I see on JQueryUI website, that we need a list of ul and li to make it.
So i create the following code in WebSharper.
let Menu =
let atr = Attr.NewAttr("test")
let el2 =
Div [
Text "menu1"
Text "menu2"
]
let menuId = "menu"
let el =
UL [
LI [
Text "menu1"
UL [
LI [Text "sub-menu1"]
] :> IPagelet
]
LI [Text "menu2"]
]
let menuJS = Menu.New(el)
Div [menuJS ]
let Main () =
Div [
H1 [Text "Titre 1"]
Menu
]
This allow me to create a basic structure of ul and li. And after, that i use it to create the menu.
But i can't obtain the sub-menu. And more over, I don't know how to interact with the menu, like catching select element, etc.
I find no documentation about menu with JQueryUI on the WebSharper samples.
Can you please help me understand how to use it ?

There seems to be some incompatibility between jQuery 1.11 and jQuery UI 1.10, which are the versions linked by WebSharper.
I just updated WebSharper.JQueryUI to reference jQuery UI 1.11, so updating the NuGet package to the latest (2.5.7.186) will make this work.

Related

How can I change the background color of the <body> element in Fable / Fulma?

Here's a snippet of my client web app written in F# using Fable (for compilation to Javascript) and Fulma (for CSS rendering)
let view (model: MyModel) dispatch =
div [ Style [CSSProp.BackgroundColor "green"]] [
Button.button [ Button.Size IsSmall ] [ str "START" ]
]
Currently, only the background color of the div block is set to green. I know I could hard-code this into index.html or bulma.css to change the background color of the entire HTML page but I am looking for a way to do this in F# according to the rules established by Fulma.
I have not actually used Fulma myself, but I had a quick look at the default Fulma template. The way this works is that you have a <div> element with id elmish-app in the index.html:
<body>
<div id="elmish-app"></div>
</body>
And the F# code specifies to use the <div> element to show the elements generated by view:
Program.mkProgram init update view
|> Program.withReactSynchronous "elmish-app"
|> Program.run
Given this, you could try to add id to your body element and then generate HTML content including the body element in your view. If React actually replaces the original element with whatever you generated from view (rather than just adding that as nested element), this trick could work.
After studying the layout options of Fulma/Bulma here I was able to change the background color of the entire page in a Fulma-compliant way:
let view (model: MyModel) dispatch =
Hero.hero [ Hero.Color IsSuccess
Hero.IsFullHeight ]
[ Hero.body []
[ Button.button []
[ str "START" ]]]
As a matter of fact, the Hero layout option proved to be quite versatile, e.g. you can have different portions of the background covered with Hero.IsLarge, Hero.IsHalfHeight etc ...

JQueryUI in Chrome extension content script

After putting jquery-ui(css and js) and jquery in the manifest, I can use jq selectors ($), however jquery-ui seems to be inaccessible. For example, I'm trying to insert a resizable div in a content-script (content_script.js):
var $div = document.createElement('div');
$div.id = 'divId';
$div.innerHTML = 'inner html';
$("body").append($div);//works without error
$("#divId").css("background-color","yellow");//works
//doesn't give resizable handles, however works in a regular html file:
$("#divId").resizable();
//however this also has issue:
document.getElementById("divId").style.resize = "both";
Manifest:
"css":["jquery-ui.css"],
"js": ["jquery-ui.js","jquery.js","content_script.js"]
Wrong load order - jquery-ui expects jquery to be loaded first.
"js": ["jquery.js", "jquery-ui.js", "content_script.js"]

WebSharper JQuery Mobile Page Hidden

I'm trying to put together a JQuery Mobile site using the F# WebSharper Framework. In WebSharper parlance I have created a Pagelet using JQueryMObile controls which is being served by a Sitelet. Everything compiles and runs, the problem is in the html that is generated.
The page I have declared (simplePage) clearly exists in the markup and is marked with the JQueryMobile css class ui-active to make it visible. However, it is surrounded by a div that is also a page but is not marked with the active css class, making it invisible. Therefore my page inside this div is hidden. I am not creating this containing page div. It seems to be a side-affect of loading the JQueryMobile script in the html head. How can I get rid of it?
I have taken the example from http://websharper.com/samples/JQueryMobile. I am using WebSharper version 2.5.125.62 and WebSharper.JQueryMobile version 2.5.4.198. I have one relevant code file shown below followed by the generated html.
Main:
open IntelliFactory.Html
open IntelliFactory.WebSharper
open IntelliFactory.WebSharper.Html
open IntelliFactory.WebSharper.JQuery
open IntelliFactory.WebSharper.Sitelets
type Action = | Home
[<JavaScript>]
module MyJQueryContent =
let Main() =
JQuery.Mobile.Mobile.Use()
let page = Div [
Id "simplePage"
HTML5.Attr.Data "role" "page"
HTML5.Attr.Data "url" "#simplePage"
] -< [
Div[Text "content"]
]
Div [page]
|>! OnAfterRender (fun _ -> JQuery.Of(page.Body)
|> JQuery.Mobile.JQuery.Page
|> ignore
JQuery.Mobile.Mobile.Instance.ChangePage(JQuery.Of(page.Body)))
[<Sealed>]
type MyJQueryMobileEntryPoint() =
inherit Web.Control()
[<JavaScript>]
override this.Body = MyJQueryContent.Main() :> _
module Pages =
let HomePage =
PageContent <| fun context ->
{ Page.Default with
Title = Some "Index"
Body = [IntelliFactory.Html.Tags.Div[new MyJQueryMobileEntryPoint()]] }
[<Sealed>]
type Website() =
interface IWebsite<Action> with
member this.Sitelet = Sitelet.Content "/" Home Pages.HomePage
member this.Actions = [Home]
type Global() =
inherit System.Web.HttpApplication()
member g.Application_Start(sender: obj, args: System.EventArgs) =
()
[<assembly: Website(typeof<Website>)>]
do ()
Output:
As a side note, you are creating one of the containing DIVs when you write Div [page] instead of page before adding OnAfterRender, but indeed this is not your problem.
As Omar describes, with jQuery Mobile you need to carefully control when and how the initialization of the page structure takes place, especially when working with dynamic pages. I recall seeing your exact problem before but I can't find that conversation in my email box, however, here is an earlier article that has some useful bits for tapping into JQM page initialization:
http://fpish.net/blog/JankoA/id/3362/201367-jquery-mobile-page-reuse-with-websharper
When jQuery Mobile framework is loaded, it checks if there is a page div in DOM. If not, it wraps body's content in page div. To control this behavior, you need to prevent jQM's autoInitializePage in order to initialize manually $.mobile.initializePage() whenever you want.
You need to listen to mobileinit event to override autoInitializePage. The code should be placed after jQuery (core) and before jQuery Mobile libraries in head.
/* jQuery.js */
$(document).on("mobileinit", function () {
$.mobile.autoInitializePage = false;
});
/* jQuery-Mobile.js */
Now you can initialize jQuery Mobile whenever you want by calling $.mobile.initializePage().
I am a developer of WebSharper. Omar is right, this is a JQM thing, another workaround for it is having a dummy page node in the sitelet. Like this:
module Pages =
open IntelliFactory.Html
let HomePage =
PageContent <| fun context ->
{ Page.Default with
Title = Some "Index"
Body =
[
Div [HTML5.Data "role" "page"; Id "dummy"]
Div [new MyJQueryMobileEntryPoint()]
] }

Append html to div not working on cordova iOS

I am using cordova 2.2.0 with Xcode 4.5.2. On one of my pages I have a select component and once a particular option is selected I want to display a table within a div. My html looks like this: <div class="hero-unit" id="#facprog"></div>
The javascript/jquery looks like this:
<pre><code>
$(function() {
$('#selFaculty').change(function() {
var facultyName = $('#selFaculty').val();
var progDetails = app.fillFacultyProgramme(facultyName);
alert(progDetails);
$('#facprog').append(progDetails);
});
});
</code></pre>
Note that #selFaculty is the id of the select object. However, when the select option changes, everything in javascript executes except for the append. Nothing shows up in the div. Is there a different way to add html element to a div in jquery under cordova 2.2.0 in iOS?
Thanks in advance,
José
With jquery you can refresh a div.
This is a good example:
<script>
var auto_refresh = setInterval(
function()
{
$('#loaddiv').fadeOut('slow').load('reload.php').fadeIn("slow");
}, 20000);
</script>
and now you need to put the div in the body section of your page
<div id="loaddiv">
</div>
from http://designgala.com/how-to-refresh-div-using-jquery/
and there is another example here:
refresh div with jquery
The first example is useful when you need to load a script and refresh and the second one is useful when you need to make a change, e.g. append html and then refresh as in your case.

autocomplete of words in the middle (jQuery UI)

Anyone know good sample code using jQuery UI's autocomplete widget that can autocomplete words in the middle of a text box, not just autocomplete of the word at the end only?
I'm using the jquery UI autocomplete widget for a component that supports entry of multiple tags. It's like like stack overflow's tag editor, but simpler: no fancy formatting in the autocomplete dropdown, no "tag" background images in the edit box. I started with the jQuery UI Autocomplete Multiple sample and modified it.
It's working OK, except autocomplete doesn't work for tags in the middle of a multi-tag string. For example, if I type C Fortran and then put the caret right after C and type +, I'd expect to see C++ in the autocomplete list but instead I see Fortran again.
Here's the code so far: http://jsfiddle.net/WCfyB/4/
This is the same problem described by autocomplete in middle of text (like Google Plus), but the problem in that question was simpler because he could rely on an empty # in the text to signal when to show the autocomplete. In my case, I can't just rely on the text-- I actually need to find out where the caret is and autocomplete for the word where the caret is.
I could build this myself using caret or another plugin, but was wondering if there was already a jQuery-UI-based sample online that I could use without re-inventing another wheel, especially if there are browser-specific corner cases to worry about. Ideally, it'd behave like this: whenever the user places the caret inside or at the end of a tag (where tags are always separated by 1+ spaces), autocomplete is shown for that tag. Know a good sample?
I don't know of any examples like this, but here's something that you could start with:
var availableTags = [ ... ];
function split(val) {
return val.split(/ \s*/);
}
function extractLast(term) {
return split(term).pop();
}
$("#tags")
.bind("keydown", function(event) {
// don't navigate away from the field on tab when selecting an item
if (event.keyCode === $.ui.keyCode.TAB
&& $(this).data("autocomplete").menu.active) {
event.preventDefault();
}
})
.autocomplete({
minLength: 0,
source: function(request, response) {
var results = [],
selectionStart = this.element[0].selectionStart
term = extractLast(request.term.substring(0, selectionStart));
if (term.length > 0) {
results = $.ui.autocomplete.filter(availableTags, term);
}
response(results);
},
focus: function() {
return false; // prevent value inserted on focus
},
select: function(event, ui) {
var terms = split(this.value.substring(0, this.selectionStart));
terms.pop(); // remove the current input
terms.push(ui.item.value); // add the selected item
this.value =
$.trim(terms.join(" ") + this.value.substring(this.selectionStart)) + " ";
return false;
}
});
Example: http://jsfiddle.net/WCfyB/7/
The major caveat here is that the selectionStart method does not work in IE. You can replace those function calls with one of those plugins you mentioned in your question.

Resources