Knockout text databind erasing part of my Markup - data-binding

I'm facing a small problem regarding Knockout JS databind on a span. I want to bind a number alongside a percentage symbol. My original HTML markup is this one:
<span>10</span><span>%</span>
Then, I'd try to make the number dynamic with the following expression (I'm forfeiting the JS as it works corrctly and I don't think it's necessary for my case):
<span data-bind="text: cartTotalPrice" /><span>%</span>
Misteriously, the that contains the % symbol disappears, only displaying the binded number. But then if I do the following, the number and the symbol are correctly displayed:
<span data-bind="text: cartTotalPrice() + '%'" />
Why does this happen? Is it normal?
Thanks.

I believe the problem is that you are not closing your span tag. Use an explicit closing </span>.
<span data-bind="text: cartTotalPrice"></span><span>%</span>

Related

How can I hide <div> in an HTML page in ASP.NET?

I have one div as the following:
<div>
<% # IIF(DataBinder.Eval (Container.DataItem,"Specifiction2").ToString()<> "","")
<div>
I want to hide the above div when "spcefication2" is blank on a .aspx page.
How can I do it?
A couple of things.
You are using IIF, but IIF should never be used. Always use IF instead. The only reason to use IIF is you are stuck with a pre-2008 compiler, and even then, you should use something else.
The easiest way to do what you are describing is via an id and runat="server", you can then either set the visible property (which will mean that the div never gets emitted) or set the style to display:none
If you want to do it inline, per your example, the code is
<div style="display:
<%# IF(string.isnullorwhitespace(DataBinder.Eval(Container.DataItem,"Specifiction2").ToString), "none", "block") %>">
</div>
You are using Eval and container.dataitem, you should look into using ItemType For your grid/repeats, then referencing the value as item.Specification
The above would be much easier if you declared a function in your code behind, taking a string and returning the string none/block.

Is there a proper way to wire up Trix editor with Livewire?

When wiring together Trix editor content with Livewire, I am stumbling into problems. I believe that the issue is that when Livewire receives content from Trix, the content is swapped out and Trix becomes disabled. Is there a better way?
What I have done, that works, is as follows. At the moment, the page is the redirected to itself in order to reboot Trix (defeating the whole point of Livewire, but it's being used for other things too).
<div>
<input
id="newCommentTextTrixContent"
type="hidden"
wire:model="newCommentText"
>
<trix-editor
id="newCommentTextTrixEditor"
input="newCommentTextTrixContent"
></trix-editor>
<button wire:click="addComment(document.getElementById('newCommentTextTrixEditor').innerHTML)">Add Comment</button>
</div>
I have tried
wire:model on the hidden input -- nothing happens
x-on:trix-change="$set('comment', $event.target.innerHTML) -- this works, but Trix goes grey and ceases to work after the first keypress (reboot problem?)
I'm sure something like the latter is better, but with Trix somehow being rebooted each time. It all seems a bit messy - so the question is, what's the right way to do this?
I got it working. With up to date Livewire and Alpine installations, the code is roughly as follows.
<div wire:ignore>
<trix-editor
class="formatted-content"
x-data
x-on:trix-change="$dispatch('input', event.target.value)"
x-ref="trix"
wire:model.debounce.60s="newCommentText"
wire:key="uniqueKey"
></trix-editor>
</div>
Why does this work?
You need wire:ignore on the parent node, because Trix inserts the toolbar above the text area. wire:ignore stops Livewire from worrying about it and therefore not removing it or messing with it on the next cycle.
You need a wire:key because the DOM moves around a bit, and this helps Livewire to keep track of it.
I propose the long debounce, which is a hack as the .lazy modifier doesn't work well with text. Also, waiting for Ajax on each key press is painful.
The alpine event ensures that Trix events (like bold, italics etc) are still fired
That's it. I use this above to repetitively submit comments onto the end of a comment stream, and everything seems to work fine. Good luck!
Note, I also have CKEditor working similarly, as described here.
As an extension on #Kurucu 's answer, and the comment under it from #Rehan;
This seems to work very well. But when I apply styles like li or bold
it doesnt retain in the wire:model. Ex:
<div>foo<br>bar<br>foobar</div> I applied the Bullets here the tags
are missing. Did you face this issue? – Rehan
To fix the issue of not having an updated value when pressing buttons bold, italic, or quote for example, add the following part to the trix editor (note the x-on:trix-change="$dispatch('input', event.target.value)"):
<div wire:ignore>
<trix-editor
class="formatted-content"
x-data
x-on:trix-change="$dispatch('input', event.target.value)"
wire:model.debounce.1000ms="newCommentText"
wire:key="uniqueKey"
></trix-editor>
</div>
The above option works but wasn't getting the data back from my field, Here's what worked for me with a little tweak using AlpineJS's #entangle.
Below is my working solution:
<div class="mb-2" x-data="{ description: #entangle('description').defer }"
x-init="$watch('description', function (value) {
$refs.trix.editor.loadHTML(value)
var length = $refs.trix.editor.getDocument().toString().length
$refs.trix.editor.setSelectedRange(length - 1)
}
)" wire:ignore>
<label class="form-label">Job Description <span class="text-danger">*</span></label>
#error('description')
<span class="error d-inline-block"><i class="mdi mdi-alert-circle"> </i> {{$message}}</span>
#enderror
<input name="description" id="description" type="hidden" x-model="description">
<div x-on:trix-change.debounce.1000ms="description = $refs.trix.value">
<trix-editor x-ref="trix" input="description" class="overflow-y-scroll"
style="height: 20rem;"></trix-editor>
</div>
</div>
I got it to work by using Trix's built-in events.
<input id="about" name="about" type="hidden" value="{{ $about }}">
<trix-editor input="about" class="wysiwyg-content"></trix-editor>
<script>
var about = document.getElementById("about")
addEventListener("trix-change", function(event) {
console.log(about.getAttribute('value'));
#this.set('about', about.getAttribute('value'))
})
</script>

Rails: inline CSS retrieve style from database entry

In my HTML I have a span
<span style="color:#??????>
<h3>Title</h3>
</span>
Okay, in my database I have records which have a field that store the hash color value of a span, example #123456 , with the hash included.
Now what I want to do is in the HTML, instead of me specifying the colour, it is retrieved directly from the database.
The model is called Sauce. The field is called title_colour.
I have tried:
<span style="color: #{sauce.title_colour}">...</span>
The problem is that when the HTML is output, it is exactly as it is in the code. It does not extract the database value.
I think the problem is because in Rails when we display an object when already in quote marks, we start with a #, eg #{sauce.field_name} , and in CSS the color value also starts with a #.
Any help?
You need to use the proper erb interpolation tags:
<span style="color: <%= sauce.title_colour %>">...</span>

How do I bind a dynamic set of jQuery Mobile buttons using Knockout.js?

I'm using jQuery Mobile (jQM) and Knockout.js (ko) to develop an application. In this application, I need to generate a variable number of buttons that are defined by a constantly updating web service.
So, in my markup, I have:
<div id="answerPage-buttons" data-bind="foreach: buttonsLabels">
<button data-role="button" data-inline="true" data-theme="b" data-bind="text: text, click: $root.submitAnswer" />
</div>
buttonLabels is a list of short strings returned from the web service. It's defined as:
self.buttonLabels = ko.observableArray();
This all works fine when the buttons are not "jQM styled". However, when I style them using:
$("#answerPage-buttons").trigger("create");
problems arise during the update.
The issue seems to be that jQM wraps the buttons in a div (with a sibling span) to make them all nice and mobile looking. However, when the ko applies the updates via the bindings, it only removes the tags, leaving the surrounding stuff, and adds new button tags - which are then also styled by the jQM trigger call.
So, I end up with an ever-growing list of buttons - with only the last set being operational (as the previous ones are gutted by the removal of their button element, but all the styling remains).
I've managed to address this, I think, by placing the following call immediately after the observable is updated:
$("#answerPage-buttons div.ui-btn").remove();
However, my feeling is that there's probably a better approach. Is there?
I found a solution.
If I surround the buttons with a div, it seems to work - e.g.
<div id="answerPage-buttons" data-bind="foreach: buttonsLabels">
<div>
<button data-role="button" data-inline="true" data-theme="b" data-bind="text: text, click: $root.submitAnswer" />
</div>
</div>
I'm guessing this is because the markup added by jQM remains "inside" the markup replicated by ko. Without the div, jQM wraps the button tag, which was the immediate child of the tag that contains the ko foreach binding.

Convert textarea value to something suitable for span

I have data taken from a textarea and put into a database. It is then returned from the database, and I want to put it into a span tag with the formatting still intact. Is there a method that does this? I have tried
.Replace("\r\n", "<br />")
which fixes the line breaks, but that still leaves the whitespace and.. I am sure there has to be a built-in method somewhere.
Easiest solution is to mark your span as pre-formatted:
<span style="white-space:pre">text from textarea here</span>

Resources