I am using CoffeeScript and HAML. I have objects list:
{
title: "Title"
url: "http://example.com"
image_url: "img.png"
attributes: {
target: '_blank'
}
}
{
// ...
}
And I have a template:
- for item in #model.data
%a.menu-item{"href": item.url}
Can I somehow parse "attributes" if it is exists and add to %a.menu-item element to get <a href="[item.ur]" target="_blank">
If you want to merge all attributes from your hash, this should work:
%a.menu-item{item['attributes'], "href" => item['url']}
To conditionally include a tag element, use defined? The trick is in the ternery - setting the attribute value to nil will remove it. (https://gist.github.com/orioltf/3145400)
As an example (trying to mock up your situation with some quick ruby code)
- _h1 = {'title' => 'Title', 'url' => "http://example.com", 'image_url'=> "img.png", 'attributes'=> {'target'=> '_blank'}}
- _h2 = {'title' => 'Title2', 'url' => "http://example2.com", 'image_url'=> "img2.png"}
- $data_list = [_h1, _h2]
- class Model; def data() $data_list end end
- #model = Model.new
- for item in #model.data
%a.menu-item{:href => item['url'],
:target => (defined? item['attributes']['target']) ? item['attributes']['target'] : nil}
Note here that I am using hash accessors. Depending on your your objects are set up, what framework you are using, you may use what i did, item.url, item.get('url'), etc.
You can test it out with haml test.haml test.html
Hope that gets you started.
Related
I am trying to add a new key-value pair to the already loaded JSON Array. I am adding the new key-value pair to customize the header column cells in react bootstrap table but getting the below errors. Can any one please help?
'Columns' in the below state is where I wanted to add new key-value pair
state = {
data: MYResult.Products || [],
actualData: MYResult.Products || [],
columns: MYResult.ParametricList_Attributes || [],
isCompareClicked: false,
isDisabled: true,
selected: []
};
This is how I am adding the key-value pair -
componentDidMount(){
checkbox = (column, colIndex) => {
return (
<h5>{ column.text }<checkbox/></h5>
);
}
console.log(this.state.columns) ;
newColumn = this.state.columns.map((column) => {
return {...column, headerFormatter: checkbox};
});
this.setState({columns: newColumn });
}
Full code here - https://codesandbox.io/s/o1r988qkz Please uncomment the componentDidMount() to see the issue
Firstly, there's a typo in dcolumn and column.
And regarding the not defined error, you need to define it using const. Use like:
const checkbox = (column, colIndex) => {
return (
<h5>{column.text}<checkbox /></h5>
);
}
JavaScript variables need to be declared when they are used. Public class syntax can not be used everywhere. The error you're getting is self-evident - 'checkbox is not defined'.
Refer this on how to use it: https://tylermcginnis.com/javascript-private-and-public-class-fields/
I simply declared the undeclared variables in your example and the code worked.
Controller side:
$regs = Model::all('id','name');
return view('aview',compact('regs'));
View side:
{{ Form::select('id', $regs) }}
The dropdown gets rendered and populated but displays JSON objects such as {"id:1","name: Aname"} instead of displaying Aname and setting the post value to 1
Try this
In your controller
$regs = Model::pluck('name','id');
Keep your view same
Hope this will work
You can populate like this:
{!! Form::select('id', $regs->lists('name', 'id'), null, ['class' => 'form-control']) !!}
Form::select accepts four parameters:
public function select($name, $list = [], $selected = null, $options = []);
The name of the html field
the list of options
the selected value
an array of html attributes
You can generate the list by using
$regs = Model::all('id','name');
$plucked = $regs->pluck('name', 'id');
// $plcuked = ['id1' => 'name1', 'id2' => 'name2' ...]
And the blade code should look like this
{{ Form::select('name', $plucked, null, ['class' => 'form-control']); }}
I maybe making this problem a bit complicated but I think its worth using the plugin.
You can take the use of very popular plugin - Select2. This plugin of jQuery helps you to fetch data from server and populate the fetched data into our dropdown in minutes. Your code goes like this.
// Code in your Controller Method
$regs = Model::all();
$data = [];
foreach($regs as $reg) {
$data[] = [
'id' => $reg->id,
'text' => $reg->name
];
}
return json_encode(['items' => $data]);
// Code in your desired View
<select id="select_items"></select>
// Code in js
$('#select_items').select2({
ajax: {
url: '/example/api', // <--------- Route to your controller method
processResults: function (data) {
return {
results: data.items
};
}
}
});
You can also integrate search options using this plugins as it helps you to fetch results based on your search keywords (for more see Select2 Examples). Hope this helps you to solve your problem.
I have a table named Play and I'm showing details of each record in Yii2 detail view widget. I have an attribute in that table recurring which is of type tinyint, it can be 0 or 1. But I don't want to view it as a number, instead i want to display yes or no based on the value (0 or 1).
I'm trying to change that with a function in detailview widget but I'm getting an error: Object of class Closure could not be converted to string
My detail view code:
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'name',
'max_people_count',
'type',
[
'attribute' => 'recurring',
'format'=>'raw',
'value'=> function ($model) {
if($model->recurring == 1)
{
return 'yes';
}
else {
return 'no';
}
},
],
'day',
'time',
...
Any help would be appreciated !
Unlike GridView which processes a set of models, DetailView processes just one. So there is no need for using closure since $model is the only one model for display and available in view as variable.
You can definitely use solution suggested by rkm, but there is more simple option.
By the way you can simplify condition a bit since the allowed values are only 0 and 1:
'value' => $model->recurring ? 'yes' : 'no'
If you only want to display value as boolean, you can add formatter suffix with colon:
'recurring:boolean',
'format' => 'raw' is redundant here because it's just text without html.
If you want add more options, you can use this:
[
'attribute' => 'recurring',
'format' => 'boolean',
// Other options
],
Using formatter is more flexible approach because these labels will be generated depending on application language set in config.
Official documentation:
DetailView $attributes property
Formatter class
Formatter asBoolean() method
See also this question, it's quite similar to yours.
Try
'value' => $model->recurring == 1 ? 'yes' : 'no'
Within a sinatra framework, I'm trying to yield a template, dashboard.haml, within a layout template: layout.haml. But when the page loads, a stringified version of the html appears, instead of the HTML itself. So it's clearly fetching the correct template, but I wonder why the html is being rendered as a string??
Here are the relevant code:
server.rb
get '/:developer' do
#workflow_audits = Auditor.new(params['developer']).workflow_audits
haml :dashboard, :layout => :layout
end
views/layout.haml
%html
%head
%title Workflow Stuff
%link{ :rel => :stylesheet, :type => "text/scss", :href => "/stylesheets/dashboard.scss"}
%script{ :src => "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js" }
%body
%form{action: '/', method: 'post'}
%label{for: 'developer'}Select a developer:
%input{type: 'text', name: 'developer'}
%input{type: 'submit', value: 'submit'}
= yield
views/dashboard.haml
%ul.issue-list
- #workflow_audits.each do |audit|
%li.issue
.issue-container.row
You have an indentation issue in dashboard.haml. I removed the 3 spaces and tabs in your post and put two spaces everywhere, all errors went away and was able to get it working.
%ul.issue-list
- #workflow_audits.each do |audit|
%li.issue
.issue-container.row
is there a way to split a logstash (1.4.2) event into multiple other events?
My input looks like this:
{ "parts" => ["one", "two"],
"timestamp" => "2014-09-27T12:29:17.601Z"
"one.key=> "1", "one.value"=>"foo",
"two.key" => "2", "two.value"=>"bar"
}
And I'd like to create two events with the following content:
{ "key" => "1", "value" => "foo", "timestamp" => "2014-09-27T12:29:17.601Z" }
{ "key" => "2", "value" => "bar", "timestamp" => "2014-09-27T12:29:17.601Z" }
Problem is that I can't know the actual "parts"...
Thanks for your help :)
Updating a very old answer because there is a better way to do this in newer versions of logstash without resorting to a custom filter.
You can do this using a ruby filter and a split filter:
filter {
ruby {
code => '
arrayOfEvents = Array.new()
parts = event.get("parts")
timestamp = event.get("timestamp")
parts.each { |part|
arrayOfEvents.push({
"key" => event.get("#{part}.key"),
"value" => event.get("#{part}.value"),
"timestamp" => timestamp
})
event.remove("#{part}.key")
event.remove("#{part}.value")
}
puts arrayOfEvents
event.remove("parts")
event.set("event",arrayOfEvents)
'
}
split {
field => 'event'
}
mutate {
rename => {
"[event][key]" => "key"
"[event][value]" => "value"
"[event][timestamp]" => "timestamp"
}
remove_field => ["event"]
}
}
My original answer was:
You need to resort to a custom filter for this (you can't call yield from a ruby code filter which is what's needed to generate new events).
Something like this (dropped into lib/logstash/filters/custom_split.rb):
# encoding: utf-8
require "logstash/filters/base"
require "logstash/namespace"
# custom code to break up an event into multiple
class LogStash::Filters::CustomSplit < LogStash::Filters::Base
config_name "custom_split"
milestone 1
public
def register
# Nothing
end # def register
public
def filter(event)
return unless filter?(event)
if event["parts"].is_a?(Array)
event["parts"].each do |key|
e = LogStash::Event.new("timestamp" => event["timestamp"],
"key" => event["#{key}.key"],
"value" => event["#{key}.value"])
yield e
end
event.cancel
end
end
end
And then just put filter { custom_split {} } into your config file.
For future reference and based on #alcanzar answer, it is now possible to do things like this:
ruby {
code => "
# somefield is an array
array = event.get('somefield')
# drop the current event (this was my use case, I didn't need the feeding event)
event.cancel
# iterate over to construct new events
array.each { |a|
# creates a new logstash event
generated = LogStash::Event.new({ 'foo' => 'something' })
# puts the event in the pipeline queue
new_event_block.call(generated)
}
"
}