I'm trying to use both elm-css and elm-bootstrap in the same project but it looks like they don't get along well.
What I like about elm-css is that it's a drop-in replacement for the html core modules, and by just using other imports and composing your main view with toUnstyled, you get all the goodies.
{ view = view >> toUnstyled, ... }
But elm-bootstrap functions don't expect to receive the elm-css styled elements so we must remove the styles, cluttering my code with calls to toUnstyled everywhere, like i.e.
Table.td [] [ toUnstyled <| text "Hi!" ]
I could live with that, but the real show stopper appears when we need to add attributes like i.e.
Table.td [ Table.cellAttr <| class "text-center" ]
[ toUnstyled <| text "Hi!" ]
This only works if class is from core Html module, not elm-css. It would work if we could use toUnstyled <| class "text-center, but this function (for attributes) is "missing" in elm-css (the quotes are there because I'm not sure if it even makes sense to have it, fromUnstyled exists though).
So, is toUnstyled for attributes really missing?, are there any other viable options for having what both libs offer?
In terms of options, what should be done to elm-bootstrap to make it accept elm-css styled attributes? should it be a wrapper lib that calls to toUnstyled before each call to elm-bootstrap? Any thoughts?
Related
In a sample project, I placed the "Flexbox Wrapper" code sample here (picking from the drop-down list)
The code below is meant to create 2 columns for the children form components of cheese options and toppings:
...preceding code...
{
"component": "div",
"class": "flex-wrapper",
"children": [
....
However it shows both as one column (see image attached.) I have absolutely no other styling asides the header link pointing to the default snow.min.css at by CDN.
This is so basic, surprised it's not working as documented. Is there any implicit step I have missed to get this working?
Also not sure why the heading, represented by an 'h3' component in the schema, is appearing as a different font.
I have been trying to write a custom tag helper and match it to a tag/attribute with HtmlTargetElementAttribute, however I've ran into an issue where the tag helper seems to apply to every tag on the page—even those that shouldn't match. The following is a reduced case that I could reproduce it with, and as far as I understand, this should match only on <test custom> elements:
[<HtmlTargetElement ("test", Attributes = "custom", TagStructure = TagStructure.NormalOrSelfClosing)>]
type CustomTagHelper () =
inherit TagHelper ()
override __.Process (_, output) =
output.Content.SetContent("Test")
|> ignore
Now, if I look at that in something like ILSpy, the HtmlTargetElementAttribute displays in C# as:
[HtmlTargetElement("test", Attributes = "custom", TagStructure = )]
but I'm not sure if that actually affects the IL or if that's just a bug in ILSpy. However, if I actually remove the TagStructure parameter, then the tag helper works as I would have expected, only working on <test> elements with a custom attribute. Additionally, I tried saving the enum value in a separate constant:
[<Literal>]
let tagStructure = TagStructure.NormalOrSelfClosing
and using that in the attribute, which does actually work as well. But then strangely I tried setting that constant to a different enum value, but reverted the attribute definition back to what I had initially, and that worked as well.
So now I've only confused myself even more and I've likely missed something simple along the way.
Sylius 1.0.0-dev
I'm trying to modify the Quantity field of CartItemType.
Following the old docs I have created a new FormType on my Bundle and extends from original in Symfony/Bundle/CartBundle/Form/Type/CartItemType.
My custom CartItemType shows like this:
use Sylius\Bundle\CartBundle\Form\Type\CartItemType as BaseType;
use Symfony\Component\Form\FormBuilderInterface;
class CartItemType extends BaseType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->remove('quantity')
->add('quantity', 'hidden', [
'attr' => ['min' => 1, 'max' => 1],
'data' => '1',
'label' => 'sylius.form.cart_item.quantity',
])
->setDataMapper($this->orderItemQuantityDataMapper);
}
}
I want you can't buy more than one product quantity per order.
My config seems liike this:
sylius_cart:
resources:
cart_item:
classes:
form:
default: Dinamic\Bundle\SyliusRibBundle\Form\Type\CartItemType
When I open some product view i'm getting this error:
The option "product" does not exist. [...] in #SyliusShop/Product/Show/_inventory.html.twig at line 4
Any idea about why this is happening?
Instead of extending CartBundle CartItemType extend using this:
use Sylius\Bundle\CoreBundle\Form\Type\CartItemType as BaseType;
The CoreBundle CartItemType class extends the CartBundle CartItemType, so if you extend the wrong class it will break everything
Don't extend Symfony form types that way - extend Symfony\Component\Form\AbstractType instead, and implement getParent() in your custom type:
public function getParent()
{
return BaseType::class;
}
That way, the parent's options will be available to your custom type as well, and everything will be properly rendered/initialized.
Edit:
Technically, both approaches should work. However, using inheritance will completely override the parent form's behavior, while using getParent() will add your custom behavior to the parent's form.
getParent() will tell Symfony to build the form defined in that method first, and then use that as the base for your own implementation. So when using that, the FormBuilder in your buildForm() method will already contain the complete parent form, ready for your own modifications, the OptionsResolver in your configureOptions() method will already have the parent form's options and defaults defined, etc. which appears to be exactly what you want (otherwise your call to $builder->remove() makes very little sense). When using inheritance, you'll have to take care to do everything the parent form does which you want to do as well, which might very well break when the parent form changes.
Another difference is in Symfony's form extensions. When implementing getParent(), any form extensions applied to the parent form will be applied to your custom form as well. When using inheritance, that won't be the case.
The first point is easy to work with (parent::buildForm() will ensure you have the correct fields, for instance), but the second is not as easy. Generally you want these extensions to apply to your custom form type as well - in this case there's actually a decent chance the error is caused by a form extension not being applied to your custom type.
So basically, use getParent() whenever possible. Use inheritance for form types only if you want to completely override behaviour or you explicitly want form extensions not to apply to your custom type.
Disclaimer: I'm brand new to Elm
I'm fiddling around with the online Elm editor and I've run into an issue. I can't find a way to get certain special characters (copyright, trademark, etc.) to show up. I tried:
import Html exposing (text)
main =
text "©"
All that showed up was the actual text ©. I also tried to use the unicode character for it \u00A9 but that ended up giving me a syntax error:
(line 1, column 16): unexpected "u" expecting space, "&" or escape code
The only way I found was to actually go to someone's website and copy/paste their copyright symbol into my app:
import Html exposing (text)
main =
text "©"
This works, but I would much rather be able to type these characters out quickly instead of having to hunt down the actual symbols on other websites. Is there a preferred/recommended method of getting non-escaped text when returning HTML in Elm?
Edit:
Specifically for Mac:
option+g gives you ©
option+2 gives you ™
option+r gives you ®
All tested in the online editor and they worked. This still doesn't attack the core issue, but it's just something nice to note for these specific special characters.
Why this is (intentionally) not so easy
The "makers" of Elm are understandably reluctant to give us a way to insert "special" characters into HTML text. Two main reasons:
This would open a "text injection" hole where a malicious user could insert any HTML tags, even JavaScript code, into a Web page. Imagine if you could do that in a forum site like Stack Overflow: you could trick anyone reading your contribution into executing code of your choosing in their browser.
Elm works hard to produce optimal DOM updates. This only works with the content of tags that Elm is aware of, not with text that happens to contain tags. When people insert text containing HTML tags in an Elm program, there end up being parts of the DOM that can't be optimized.
How it's possible anyway
That said, the Elm user community has found a loophole that affords a workaround. For the reasons above, it's not recommended, especially not if your text is non-constant, i.e. comes from a source outside your program. Still, people will be wanting to do this anyway so I'm going to document it to save others the trouble I had digging everything up and getting it working:
If you don't already have it,
import Json.Encode exposing (string)
This is in package elm-lang/core so it should already be in your dependencies.
Similarly,
import Html.Attributes exposing (property)
Finally, create a tag having a property "innerHTML" and a JSON-Value representation of your text, e.g.:
span [ property "innerHTML" (string " ") ] []
I found, that there is a better solution:
you can convert special characters from Unicode to char, and then create a string from char:
resString = String.fromChar (Char.fromCode 187)
You can use directly the unicode escape code in Elm strings and chars:
We have a util module containing all our special chars like:
module Utils.SpecialChars exposing (noBreakSpace)
noBreakSpace : Char
noBreakSpace = '\x00A0'
Which can be used as:
let
emptyLabel = String.fromChar noBreakSpace
in
label []
[ span [ ] [ text emptyLabel ]
]
This will render a <span> </span>
I recently created an Elm package that solves this. If you use text' "©" it'll render the copyright symbol © instead of the escape code. Also works with "©" and "©". Hope this helps!
You don't need to hunt the symbols, you can get them from a list like this one.
If it's too bothersome to copy & paste, you can also create a helper function that you can use with your escaped characters like this:
import Html exposing (..)
import String
htmlDecode str =
let
replace (s1, s2) src= String.join s2 <| String.split s1 src
chrmap =
[ ("®", "®")
, ("©", "©" )
]
in
List.foldl replace str chrmap
main = text <| htmlDecode "hello ©"
For a view, I need to define a size, a drop-down with data, set its size and get the chosen value for input in some function.
loadGui: func [] [
unview/all
view layout [
Dropd_urls: drop-down (getUrlsEnd Urls)
]
]
What is a logic behind a style or a facet? Define a word, than the facet then the size, alignment and other properties, then a block for on-action? And what about the (getUrlsEnd Urls) that gets evaluated, where should it be placed? If someone could provide a thorough example on the drop-down, it would be great.
And another question. I'm aware of the help system/..., but cannot get useful information about the logic of how to accomplish what was stated above. Where do you go to get to know how to build the view constructs? A howto? Normally, I read the howtos provided by Nick Antonnacio, but there's more to view than what is shown in his documents.
the demo on atronixengineering.com/r3/demo.r has also a dropdown list under widgets. You could generate your dropdown list with compose/deep.
view layout compose/deep [
Dropd_urls: drop-down [
(getUrlsEnd Urls)
]
]
or with different actions depending of the choice of the dropdown list
view layout [
Dropd_urls: drop-down [
"1"
"2"
] on-action [print face/facets/text]
]
did you read Cross Platform App Development with Rebol 3 Saphir ?