I'm creating a custom SimpleForm input. It utilizes a javascript modal popup to select values.
I can basically get it to work if I include the modal partial in the form view, but I would ideally like to have the custom input push the partial to the template.
However, I can't get it to work. I'm trying this, but it doesn't render the partial correctly.
class ProductCategoryImageSelectInput < SimpleForm::Inputs::CollectionSelectInput
def input
html = ''
html << 'Launch demo modal'
File.open("#{Rails.root}/app/views/product_categories/_browse_modal.html.erb", 'r') do |f|
html << f.read
end
end
end
Any thoughts?
EDIT
I'm apparently too new of a user to post screenshots, but here are links to the differences in functionality:
When I embed the modal code in the form, I get this, which is the desired functionality:
working
When I try to put the modal code in the custom input, I get this instead:
not working
You can also render partial from a custom input using the SimpleForm::FormBuilder instance which is assigned to an instance variable named #builder:
class ProductCategoryImageSelectInput < SimpleForm::Inputs::CollectionSelectInput
def input
#builder.template.render(partial: 'product_categories/browse_modal', locals: { foo: 'bar'})
end
end
Weirdly, it seems I've already answered it here.
Does this work for you?
ERB.new(f.read).result(binding)
PS: Updated with ERB instead of HAML.
Related
I have a view that renders a form with code similar to the following:
#using( var form = Bootstrap.Form().SetHorizontal( 3 ).AddCss( Css.ColSm8, Css.ColMdOffset2 ).Begin() )
{
#form.DisplayFor( m => m.Name )
// bla bla bla
#Html.Action( "Details", "Fare", new { entity = Model.FareId } )
}
How can I access the form object in the partial view, so that the same layout is applied to the whole form?
A lot of work was spent ensuring that the Bootstrap control stack would carry-over into partial views. You have two options here:
The first is to just pass the form object to the partial/action as part of the model. In your case, you would just add it as another property in the anonymous model object you're sending to the action.
You don't need to use the form instance to make FluentBootstrap recognize you're in a form. It's just a convenience to make calling the extensions appropriate to a form easier. You can also just call something like Bootstrap.DisplayFor(x => x.Name) right from the global Bootstrap object in your partial and it will respect any settings you've placed in the containing form defined in the containing view.
I'm using dojo to validate input fields and if there is an error (for eg: required field) it appears in the dojo tooltip. But, I would like to show error in the custom div instead of tooltip.
So, I'm wondering if there is a way to hide/disable the validate error to appear in the tooltip? If so, I can capture the error message shown in the hidden tooltip and show the result in custom div, which will be consistent with error styling across the application.
Please advise. Thanks.
I would recommend to use the standard Dojo validation mechanism, contrary to what vivek_nk suggests. This mechanism works great in most cases, and covers most situations (required, regular expressions, numbers, dates etc.).
To solve your issue: you can overrule the "dispayMessage" function of a ValidationTextBox (for example).
displayMessage: function(/*String*/ message){
// summary:
// Overridable method to display validation errors/hints.
// By default uses a tooltip.
// tags:
// extension
if(message && this.focused){
Tooltip.show(message, this.domNode, this.tooltipPosition, !this.isLeftToRight());
}else{
Tooltip.hide(this.domNode);
}
}
Just create your own ValidationTextBox widget, extend dijit/form/ValidationTextBox, and implement your own "displayMessage" function.
Simple solution for this scenario is not to add the "required" condition at all to those fields. Instead add a separate event handler or function to check for this validation.
For eg: add a function for onBlur event. Check if the field is a mandatory. If so, show message in the custom div as expected.
<input data-dojo-type="dijit/form/TextBox"
id="sampleText" type="text" mandatory="true" onBlur="checkMandatory(this)"/>
function checkMandatory(field) {
if(field.mandatory=='true' && field.value=="") {
alert('value required'); // replace this code with my showing msg in div
} else {
field.domNode.blur();
}
}
This above code snippet does not use Dojo for validation, rather manual. Dojo actually helps to ease this by just adding the attribute "required". If that is not required, then just ignore Dojos help for this case and go native.
So, for all fields, just add the attributes - "mandatory" & "onBlur", and add the above given function for onBlur action for all these fields.
I have a page for listing items, and I have anchors in each of the items to edit it.
So when I click on the edit link, it will take me to the edit page, which have save button and cancel button.
I want it when I click the save button it'll take me to confirmation page which have OK and cancel button.
I know in asp.net mvc you can send model into the view by this
return View("Edit", model);
It is sensible to then write each of the model property like this in the view
#Html.EditorFor( model => model.name )
#Html.EditorFor( model => model.description )
//more properties here...
So that after I click the save button, I can have the model back in the controller
But after the edit page, I only need to view a question in the confirmation page do I have to write it manually like this
#Html.HiddenFor( model => model.name )
#Html.HiddenFor( model => model.description )
//more properties here...
Is there a one line hassle free function to do this in asp.net mvc?
You can use #Html.EditorForModel() helper. However this method will produce default UI elements like textboxes. You can provide a custom template that will produce hidden inputs.
In Dojo, I am trying to extend dijit.Dialog using templates. When I instantiate it, I get only the text in the dialog box, without the borders or close button. Is there some additional step I need to do to get it fully initialized?
My template is in template.html, it looks like so:
<div dojoType="dijit.Dialog" id="dynFilter" jsId="dynFilter">
"Dynamic Dialog"
</div>
Here is the dojo.declare:
dojo.declare(
"template.dialog", // class name
[dijit._Widget, dijit._Templated, dijit.Dialog], // parent classes
{
templateString : dojo.cache("autonomics", "template.html"),
}
);
After I instantiate it, I call .startup(), which doesn't seem to do anything, then .show(), which does place it on the page, missing most of its functionality.
var dialog = new template.dialog();
dialog.startup();
dialog.show();
What am I missing?
You overwrite the template of the original dijit/Dialog when subclassing.
Have a look to my answer to Dojo Dialog with confirmation button which solves the issue you are experiencing. Or go directly to working example at jsFiddle: http://jsfiddle.net/phusick/wkydY/
I need to render some views without layout.
To skip line :render :layout=>false and if else logic from controller actions,
i have custom mime type like phtml (plain html).
Mime::Type.register "text/phtml", :phtml
this format need to render the same html views, but only without layout. I complete this with this chunk of code in app. controller:
before_filter proc { |controller|
if params[:format] && params[:format]=='phtml'
controller.action_has_layout = false
controller.request.format = 'html'
end
}
First, this is ugly, second i can't any more control this format from controller in the way:
respond_to :phtml,:only=>:index
because it will always render view with requested format phtml.
is there a better solution? example? how can i alias view formats?
Thank a lot
You can use the layout method in your controller directly:
class ProductsController < ApplicationController
layout "product", :except => [:index, :rss]
end
Or to use no layout at all:
class ProductsController < ApplicationController
layout nil
end
Check out the guide for more info.
I haven't found better solution,only update to my previous example:
before_filter proc { |controller|
if params[:format] && params[:format]=='plain_html' && controller.collect_mimes_from_class_level.include?(:plain_html)
controller.action_has_layout = false
controller.request.format = 'html'
end
}
i added this line to check is a new format defined into our controller:
controller.collect_mimes_from_class_level.include?(:plain_html)
Now we can have full new format which will render our standard html vews rather the build new views for the new format.
This can be useful if we wont to share existing html code, but build different logic based on requested format.
For example, we can easily prepare our html content for print like:
class PagesController < ActionController::Base
layout 'print',:only=>:show
respond_to :plain_html,:only=>[:show]
def show
Page.find(1)
respond_with #page
end
end
And request will be like:
http://www.example.com/pages/1.plain_html
I hope that someone will find this useful.
If u have a better approach for doing this, please share with us.
Regards