Form and List are rendering child views twice - swiftui

The following behaviour is kind of unexpected. I have a Form with a simple View inside like this:
Form {
Text("ChildView")
.onAppear(perform: { print("APPEAR") })
.onDisappear(perform: { print("DISAPPEAR") })
}
When the form is rendered the Text is appearing twice and then immediately disappears. Although the Form is rendered once the output is:
APPEAR
DISAPPEAR
APPEAR
DISAPPEAR
APPEAR
The same behaviour applies to List. I would expect that the content of the list or form is rendered only once.
Iam using XCode 12.0GM on iOS 14.

Related

How to make a NameValueCollection list editable in GlassMapper

I am trying to make a NameValueList collection editable with GlassMapper and I don't seem to be able to get to the bottom of this.
We have a list of validations that can be attached to a field and I would like to have the validation message editable in ExperienceEditor.
The collection is pre-processed when GlassMapper is retrieving the item:
Validations = glassItem.GetValidations();
#foreach(Validation validation in Model.Validations)
{
<div id="#validation.Identifier" ng-message="#validation.AngularKey" ng-cloak class="mtg-validation-msg">
#Html.Glass().Editable(validation, e => e.ErrorMessage)
</div>
}
Error that I am getting:
Failed item resolve - You cannot save a class that does not contain a property that represents the item ID. Ensure that at least one property has been marked to contain the Sitecore ID. Type: MyAssembly.Models.Validation
It is not possible to directly edit certain types of complex fields in the Experience Editor, such as Treelist, Multilist or Name Value Collection.
Instead, you should set up and use an Edit Frame. This will pop up a modal dialog allowing you to edit the field, it is not inline but means you do not need to leave the Experience Editor. This is the recommended approach to this problem.
Since you are using Glass Mapper, since version 4 you can declare Edit Frames all directly from code and now have to declare/set them up in the Core database first.
#if (Sitecore.Context.PageMode.IsExperienceEditor)
{
using (Html.Glass().BeginEditFrame(Model, "Edit", x => x.Validations))
{
<div>Edit Validations</div>
}
}
You might be interested in this blog post I wrote about adding a wrapper around the Edit Frame to make the UX more friendly.

Not able to make the navbar items dynamic in ember

I have navbar component which I have placed in an application.hbs so that it should be visible always.But I want to change the title of the navbar with each page I visit ( say I am on index page it should say "Home" , if I am on profile page it should say profile,etc).Right now what is happening is navbar title always remains "Home" for all the page.This is happening because the navbar gets rendered onlu during the time it loads the page in browser and after that it doesn't change according to page.
application.hbs
{{top-navbar dp_url=model.profile.dp_url first_name=model.profile.first_name title=title}}
{{outlet}}
Here the I am computing the value of title depending upon which page the user is.
application.js(controller)
if (currentPage === "" || currentPage === "#"){
currentState.set('title',"Home")
}
else if(currentPage === "Userprofile"){
console.log('myStudio');
currentState.set('title',"UserProfile");
}
In here the currentpage has the current url of app and I am comparing it and deciding the value of title for navbar.
But the top-navbar title value gets calculated only for the first time when user load the app in browser and not when I move ffrom one route to another.
I have also tried the Ember.Evented but not able to solve it.
I don't know what Ember.js and Ember-data version are you using, currentState is deprecated since 2.1, anyway looks like you're using a private method intended for Ember internals and not meant to be used in an application.
A possible (but maybe unnecessary complicated) way to accomplish what you want is:
Create a model with the information you want to mutate in the navbar (e.g. navbar-data).
In the route where the navbar is rendered, create and return a record for it using a fixed numeric ID (e.g. store.createRecord('navbar-data', { id: 1, title: "index" })).
Pass the created record to the component (instead of just a string).
Whenever you want to change, peek the record with store.peekRecord('navbar-data', 1) and change the value you want to change in the navbar.
Of course, the record you use for that must not be saved with record.save().

render sitecore mvc renderings programmatically

I want to get all the renderings of a content item and render each of them to html string inside an MVC action using C# code. Below is the code I am using to get all the renderings of a content item.
Item item = Sitecore.Context.Database.GetItem(someItem);
RenderingReference[] myRenderings = item.Visualization.GetRenderings(Sitecore.Context.Device, true);
foreach (RenderingReference rendering in myRenderings)
{
RenderingItem renderingItem = rendering.RenderingItem;
}
I am able to get this list and the rendering item's Id. But how can i render them to html string here?
Note: the renderings could be of any rendering type like view renderings, xsl renderings , controller renderings etc. I dont want to use the approach of WebClient or HtmlAgility pack.
Not sure what you really try to do, but this code allows you to render a rendering in a MVC action and returns the Html for this:
public ActionResult GetFirstRenderingHtml()
{
var rendering = PageContext.Current.PageDefinition.Renderings.First();
return this.View(new RenderingView(rendering));
}
This actually only returns the code of the first rendering of the current item. If you want to call this action directly, you need to add the sc_itemid parameter in the to specify the context item:
/api/yourcontroller/GetFirstRenderingHtml?sc_itemid=<item id>
If you want the Html for a complete item with all it's renderings, I suggest you create a web request to get the output.

Custom RadioSelect Rendering

I'm trying to make Django's RadioSelect widget render horizontally. I found the following SO post, that I thought had solved the problem: Align radio buttons horizontally in django forms, it basically states to use a custom Renderer, as follows:
class HorizontalRadioRenderer(forms.RadioSelect.renderer):
def render(self):
return mark_safe(u'\n'.join([u'%s\n' % w for w in self]))
class MyForm(ModelForm):
select=forms.ChoiceField(choices=CHOICES, widget=forms.RadioSelect(renderer=HorizontalRadioRenderer
But when I implement this, I still get the radio selection buttons rendering vertically. Here's a screenshot.
This is a seriois problem for my form. Any idea why it isn't working correctly? If it matters, the form is being rendered in a table.
Thanks
UPDATE:
Ok, I've tried something else. The renderer is now:
def render(self):
internal=''.join(['<span id="radio">%s</span>' % w for w in self])
return mark_safe(u'%s' %internal)
and I've added the CSS to my stylesheet:
#radio{
width: 100px;
float: left;
}
This renders the RadioBoxes inline, and looks great. But now there's an even bigger problem. As seen in my screenshot above, I have 2 choices, Yes and N/A. Right now, if I click on either yes or N/A, N/A gets selected. I thought this might be because they were both in spans with the same id, but if I change it to class="radio" the same thing happens. If I remove float: left from the CSS, then it works normally (but, of course, isn't displayed horizontally). Any idea what's causing this?
Whoa: okay.
Still not sure why having them with the same id or class caused them to behave as the same radio box, but I've come up with a solution.
The renderer now reads as follows:
def render(self):
internal = ''.join(['<li>%s</li>' % w for w in self])
return mark_safe(u'<div id="radio"><ul>%s</ul></div>' %internal)
This makes the radio boxes in an un-ordered list, surrounded by a div with an id of radio.
I then have the css:
#radio ul li label{
display:inline;
}
This puts them in a line. Nice and easy. Don't know why the other approach didn't work, when it sounded like it did for another SO user.

Django Flowplayer overlay does not submit form

I am trying to use flowplayer's overlay to load an external page that has a django form built in.
However the overlay loads the page but the submit button simply refreshes the page.
How do i actually submit the values entered in the form?
<script src="http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js"></script>
<script>
$(function() {
// if the function argument is given to overlay,
// it is assumed to be the onBeforeLoad event listener
$("a[rel]").overlay({
mask: {
color: '#ebecff',
loadSpeed: 200,
opacity: 0.9
},
effect: 'apple',
closeOnClick: false,
onBeforeLoad: function() {
// grab wrapper element inside content
var wrap = this.getOverlay().find(".contentWrap");
// load the page specified in the trigger
wrap.load(this.getTrigger().attr("href"));
}
});
});
</script>
<div class="bananas">launch</div>
my view boom has a model form.
Without seeing the actual view code, it's hard to give a helpful answer. In the future, please be sure to do so...
If you don't have the overlay programmed to redirect to the page, then submitting it to that same url might process/save the data without you noticing. Is the data being saved, or does absolutely nothing happen when you click 'submit'?
Generally, this is how it works: you need to be posting to a url, defined in urls.py, that points to a view function in your views.py. (These names are merely convention, and can be called whatever you like) You mentioned that you have a view named 'boom': is it defined in your urls.py like this?
url(r'^path/to/boom/$', 'model.views.boom',),
Check that this is defined and that your form is posting to it.
The view must then contain logic to process the request and return a response. Posting to that url will transfer a cleaned_data dictionary of form variables that can be accessed over the field names defined in the form. It looks like this: x = form.cleaned_data[x]. Check the form for its validity with form.is_valid(), and then do your processing. This can involve saving objects, running arbitrary code, whatever you wish.
To find out more, be sure to read the excellent documentation.